2013-07-26 3 views
2

Если вы должны были сделать что-то вроде:В C - освобождение памяти в различных контекстах

char array[2][5] = {"cars", "tags"} 
char array2[] = "computer"; 

Там было неявное выделение памяти, выделяемое равным (для первой строки):

sizeof(array); OR 
sizeof(char*10); 

Или, тем не менее, вы хотите это сделать.

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

char *ptr = "cars"; 
char *ptr2 = malloc(sizeof(*ptr2)*5); 
*ptr2 = "cars"; 

Я знаю, что если вы используете указатели на явно выделить память с помощью таНос, то это хорошая практика, чтобы освободить этот указатель, используя свободный (PTR);

Однако, когда вы определяете вещи, как указано выше, следующие вызовы необходимы на тех же основаниях, что и явное выделение памяти?

free(ptr); 
free(ptr2); 
free(array); 
free(array2); 

- Как и в стороне, все вышеперечисленное delcarations/инициализации являются неявными нулевыми байтами, верно?

ответ

2

Вам нужно всего лишь free память, выделенная malloc, а другие случаи, которые вы указали, являются указателями на строковые литералы или автоматические переменные (обычно выделяемые в стеке), пытающиеся освободить их, - это неопределенное поведение.

Строки стиля C: NULL завершено.

Кроме того, важно отметить, что:

*ptr2 = "cars"; 

не правильный синтаксис.

+0

И можете ли вы использовать malloc только с указателями? Как и в случае, если вы создали массив, такой как array [] = malloc (sizeof (char) * 10) или что-то еще. Я понимаю, что массивы используют указатели внутри, но мне все же интересно, если это определено, поскольку в скобках [] размер не вводится. – sherrellbc

+0

@sherrellbc, говоря, что «массивы используют указатели внутри», немного вводит в заблуждение. Ознакомьтесь с http://c-faq.com/aryptr/. –

+0

@sherrellbc 'array [] = malloc (....)' неверный синтаксис. Если вы хотите поэкспериментировать с синтаксисом, есть несколько онлайн-компиляторов, которые делают эксперимент быстрым и в основном безболезненным, и вы можете делать это везде, где у вас есть браузер: http://stackoverflow.com/questions/3916000/online-c-compiler-and- оценщик –

1

Вы должны всегда звонить free при передаче чего-то выделенного с вызовом malloc. Это означает, что вы всегда должны звонить только free с ptr2.

Кроме того, ваше назначение *ptr2 = "cars" является синтаксической ошибкой. Вам нужно будет использовать strcpy для заполнения ptr2. Как это:

char *ptr2 = malloc(sizeof(*ptr2)*5); 
strcpy(ptr2, "cars"); 

C строка нулевой байта в соответствии с соглашением, и строковыми литералами, т.е. "cars" является нулем.

1

*ptr2 = "cars"; не является действительным заявлением. Если вы хотите указать ptr2 где-нибудь еще, вам нужно использовать:

ptr2 = "cars"; 

Если вы хотите, чтобы перезаписать память ptr2 точки к, используйте strcpy:

strcpy(ptr2, "cars"); 

Только ptr2 нужно освободить - это единственное, что вы выделили malloc. Обратите внимание, что если вы назначили назначение ptr2 = "cars", упомянутое выше, вы не сможете освободить исходную память, которую вы выделили. Это логическая ошибка, известная как «утечка памяти».

+0

Я вижу. Таким образом, место памяти потеряно. Я думал, что ptr2 будет выделено памятью, а затем ptr2 = «cars»; будет храниться в слоте памяти. Итак, ptr2 фактически переназначается в стек, где был выделен строковый литерал? – sherrellbc

+0

@sherrellbc, он переназначен, но, вероятно, не в стек. Строковые литералы, вероятно, выделены в разделе данных только для чтения. –

1

Однако, когда вы определяете вещи, как указано выше, следующие вызовы необходимы на тех же основаниях, что и явное выделение памяти?

Нет, его незаконным, чтобы освободить память, не возвращенного malloc или calloc или realloc.

все вышеуказанные декартации/инициализации являются неявными строками, завершающими NULL, не так ли?

Да, эти строки называются строковые литералы и будет NULL termintaed.

1

Вам нужно только освободить память, которую вы выделили с помощью malloc, когда вы объявляете, что память статического массива автоматически освобождается в конце блока кода.

+0

char * ptr = malloc (sizeof (* ptr)); будет выделять sizeof() независимо от типа указателя, который является char. – sherrellbc

+0

Я удалил второй абзац, который был просто неправильным –

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