2010-11-29 1 views
4

[EDIT]C++ Удалить массив c-строк/другого типа массива

Хорошо, так что это имеет смысл, спасибо sharptooth и CashCow. Вы не можете удалить данные, назначенные как const, что делает строковые литералы непонятными. Так что, если я изменить инициализацию выглядеть следующим образом:

char **groups = new char*[2]; 

char *s1 = new char[10]; 
char *s2 = new char[10]; 
char c1 = 'a'; 
char c2 = 'b'; 
for(int i = 0; i < 9; i++) 
{ 
    s1[i] = c1; 
    s2[i] = c2; 
} 
s1[9] = NULL; 
s2[9] = NULL; 

groups[0] = s1; 
groups[1] = s2; 

жесткий код мой цикл так, что он будет повторять только через г = 1 и я = 2, то все работает.

Я заметил, что только int arraySize = sizeof arr/sizeof *arr; работает только тогда, когда массив назначается новым [] вместо локального. Это потому, что моя оригинальная переменная char ** groups; распадается на указатель, верно?

Теперь мне интересно, есть ли все равно, нужно ли определять данные const?


[ОРИГИНАЛ]

Я знаю, что arrays and pointers are evil, и что эти великие вещи называемые векторы и связанные списки.

Но, я новичок, когда дело доходит до управления памятью, и я чувствую себя немного мазохистом. Скажем, я делаю массив C-строк. Я знаю с this question и часто задаваемые вопросы, которые вы должны сопоставить type a = new type[len]; с delete[] a;. Или я думаю.

FAQ-Lite рассказывает об управлении зубчатыми массивами here, но он сосредоточен на матрицах, и я не уверен, относится ли оно к тому, что я делаю.

Этот код имеет смысл для меня, но не дает подтверждения (отладки на Visual Studio 2008) на delete[] a;. Что не так с этим, и как я могу выполнить эту задачу?

#include <iostream> 
using namespace std; 

int main(int argc, char* argv[]) 
{ 
    // Initialize array of C-strings 
    char *groups[] = {"testing1", "testing2"}; 

    // Sanity check 
    cout << groups[0] << endl; 
    cout << groups[1] << endl; 

    // Compute size 
    int arrsize = sizeof groups/sizeof groups[0]; 
    cout << arrsize << endl; 

    for (int i = 0; i < arrsize; i++) 
    { 
     // Since each string is a char array, free string memory with delete[] 
     cout << "Deleting element #" << i << endl; 
     delete[] groups[i]; 
    } 
    cout << "Freeing pointer array." << endl; 

    // Free the memory storing the pointers 
    delete[] groups; 

    return 0; 
} 
+4

Вы заметили, что вы удаляете [] `без вызова` new() `раньше? – Simone 2010-11-29 09:43:24

+4

Не массивы и указатели злы, их злоупотребление - зло. – sharptooth 2010-11-29 09:44:43

+0

Они злы в том смысле, что они уже вызвали много неприятностей, потому что трудно получить их правильно при любых обстоятельствах и есть альтернативы. Не потому, что им не разрешается использовать. – stefaanv 2010-11-29 10:28:51

ответ

8

Вы пытаетесь освободить строковые литералы - что это неопределенное поведение:

char *groups[] = {"testing1", "testing2"}; 
delete[] groups[i]; 

только называют delete[] на указателях, возвращаемых new[].

1

Литеральные строки - это выражения типа "testing1". Они имеют тип const char *. Они не могут быть изменены, и их нельзя удалить. Фактический текст обычно находится в статической области памяти только для чтения программы.

Вы можете создать массив символов, который доступен для записи, как это:

char group[] = "testing1";

То есть изменяемый, но вы не можете удалить его, ни вы можете продлить его, чтобы сделать его больше. Он также имеет локальный масштаб, поэтому вы не можете вернуть его из функции.

 Смежные вопросы

  • Нет связанных вопросов^_^