2010-02-15 6 views
4

У меня есть вопрос относительно свободный() в С.мы можем использовать указатель, освобожденный ранее?

Предположим, что у меня есть указатель на какой-то структуры (скажем, узел * PTR) .. после освобождения он может я инициализировать его в NULL, и чтобы она указывала на некоторое новое место используя malloc() или realloc()?

Для примера:

node *ptr=NULL; 
ptr=realloc(ptr,sizeof(node)); //works exactly like malloc 

/* Do some operations on ptr */ 

free(ptr); 

ptr=NULL; 
ptr=realloc(ptr,sizeof(node)); 

Это действительно, или это создает проблему. Причина, по которой я использовал realloc вместо malloc, заключается в том, что все мои вызовы realloc() находятся в цикле (поэтому вместо второго значения (node) во втором аргументе это фактически n * sizeof (node), где n продолжает увеличиваться .. и последнее место в этом результирующем массиве записывается с новыми данными), где память, на которую указывает ptr, продолжает увеличиваться до тех пор, пока цикл не закончится, и в этот момент мне не нужны данные в памяти, на которую указывает ptr, поэтому я думаю лучше всего освободить его. Теперь все это вложен в еще один более крупный (внешний) цикл.

Большое спасибо за вашу помощь

+0

Почему бы не написать свой вопрос на основе кода, который вы планируете использовать? Похоже, вы настолько упростили свой код, что на самом деле нет никаких сомнений относительно его законности. –

ответ

7

ptr не помнит, что было когда-то присваивается значение, и повторно использовать его снова, если он был назначен NULL ничем не отличается от использования его в первый раз.

И так как realloc() действует как malloc(), когда ему передан указатель NULL, он должен работать нормально.

+0

, но нужно ли назначать ptr = NULL перед его повторным использованием? Я попытался повторно использовать его в вызове realloc(), не назначив ему NULL, и он дал мне ошибку сегментации. – assassin

+0

и да ... был один экземпляр, где после присвоения ему NULL и вызова realloc(), как ptr = (char * *) перераспределить (PTR, (п + 1) * SizeOf (символ *)); где n = 0 ... это дало мне ошибку сегментации ... Какими могут быть возможные причины для этого? – assassin

+1

@assassin: когда вы не назначаете NULL перед повторным использованием, то вы передаете недопустимый указатель, который определенно является ошибкой. Лучше всего назначить NULL, когда вы вызываете 'free()', а не перед 'realloc()' (иначе вы могли бы назначить NULL совершенно правильному указателю и утечке памяти таким образом). –

9

Это нормально - вы не действительно повторно используете указатель, а только переменную, удерживая указатель.

+0

, но нужно ли назначать ptr = NULL перед повторным использованием? Я попытался повторно использовать его в вызове realloc(), не назначив ему NULL, и он дал мне ошибку сегментации. – assassin

+0

и да ... был один экземпляр, где после присвоения ему NULL и вызова realloc(), как ptr = (char * *) перераспределить (PTR, (п + 1) * SizeOf (символ *)); где n = 0 ... это дало мне ошибку сегментации ... Какими могут быть возможные причины для этого? – assassin

+0

В этом случае да - вы не можете полагаться на «старое» значение указателя, мешающее ему. – jldupont

3

Вы не должны думать об этом как о «освобождении указателя», но освобождая все указатели указывает на. Совершенно нормально, что указатель указывает сначала на один объект (который затем может быть освобожден), а затем на другой объект.

+0

, но нужно ли назначать ptr = NULL, прежде чем повторно использовать его?Я попытался повторно использовать его в вызове realloc(), не назначив ему NULL, и он дал мне ошибку сегментации. – assassin

+0

и да ... был один экземпляр, где после присвоения ему NULL и вызова realloc(), как ptr = (char * *) перераспределить (PTR, (п + 1) * SizeOf (символ *)); где n = 0 ... это дало мне ошибку сегментации ... Какими могут быть возможные причины для этого? – assassin

+0

Причина в том, что вы передали указатель на свободную память для перераспределения. Как вы говорите в своем коде, realloc ведет себя как malloc, когда его параметр равен NULL. Это не имеет значения. realloc обычно используется для изменения размера выделения памяти. Поэтому он ожидает, что аргумент будет указателем на часть выделенной памяти (или null). Если аргумент - это что-то еще, поведение не определено, что обычно означает segfault. –

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