Безопасно ли повторно использовать указатели переменных после освобождения того, на что они указывают? - PullRequest
11 голосов
/ 03 февраля 2009

Безопасно и предсказуемо ли повторно использовать указатели после освобождения данных, на которые они указывают?

Например:

char* fileNames[] = { "words.txt", "moreWords.txt" };
char** words = NULL;
int* wordsCount = NULL;
for ( i = 0; i < 2; ++i ) {
    data = fopen( fileNames[i], "r" );
    words = readWords( data );
    wordsCount = countWords( words );

    free( wordsCount );
    for ( j = 0; words[j]; ++j )
        free( words[j] );
    free( words );
    fclose( data );
}

* проверка ошибок пропущена

Я запускаю код, и он запускается (без предупреждений, ошибок или проблем с памятью), но мне интересно, насколько это безопасно и предсказуемо для использования в большинстве сред (особенно в типичной среде Linux)?

Если это не «безопасно и предсказуемо», каков наилучший способ выполнить одни и те же операции над двумя разными файлами, если не считать создания в два раза больше указателей и т. Д.?

РЕДАКТИРОВАТЬ: Я спрашиваю, можно ли повторно использовать указатель переменная после освобождения того, на что он указал. Я понимаю, что вы не должны использовать указатель значение после освобождения. Предположим, что код работает отлично (он работает как задумано, память освобождается правильно и тому подобное). Я не могу изменить спецификацию. для этого назначения.

Спасибо!

Ответы [ 9 ]

22 голосов
/ 03 февраля 2009

То, что вы делаете, хорошо: потому что, после того, как вы отпустите указатель, вы повторно инициализируете его, прежде чем снова его использовать.

Если вопрос «Безопасно ли повторно использовать указатель значение после его освобождения», тогда ответ «нет».

Если вопрос заключается в том, «безопасно ли повторно использовать указатель переменная после освобождения его значения», тогда ответ «да, при условии, что вы повторно инициализируете его в (новое) допустимое значение перед его повторным использованием» .

3 голосов
/ 03 февраля 2009

Да. Это безопасно. (Некрасиво, но безопасно :))

1 голос
/ 03 февраля 2009

Мне неясно, что вы подразумеваете под повторным использованием.

Если вы имеете в виду это:

int* pInt = new int;
*pInt = 3;
delete pInt;

pInt = new int;

Тогда да, это безопасно.

1 голос
/ 03 февраля 2009

Можно безопасно назначить что-то еще для того же указателя. Абсолютно НЕ безопасно повторно использовать свободную память. Когда-то много кода освободило бы блок памяти, а затем использовало бы его, как если бы оно не было освобождено. Это вызвало огромные проблемы, когда этот код был перенесен на другие операционные системы, которые не были так довольны этой парадигмой.

1 голос
/ 03 февраля 2009

Я не вижу никаких технических проблем с их повторным использованием. Это может повредить удобочитаемости и удобству обслуживания и увеличить вероятность ошибок.

1 голос
/ 03 февраля 2009

Не могу сказать. Это выглядит безопасно, но я не вижу распределения памяти, поэтому не могу быть уверен, что вы освобождаете нужные вещи.

0 голосов
/ 03 февраля 2009

Во-первых, я не вижу здесь преждевременного «освобождения» (без апострофа!). Как вы думаете, где вы получите доступ к данным, которые вы уже освободили?

Кроме того, даже если вы захотите получить доступ к данным после их освобождения, это зависит от системы, насколько это безопасно или нет. Системы могут отдать освобожденную память другим процессам для немедленного повторного использования, в то время как другие системы, особенно если вы используете довольно приватные функции lib, такие как malloc, могут просто использовать память, доступную только для этого вашего процесса, так что ничего произойдет с освобожденной памятью, потому что другие части системы не узнают об этом.

0 голосов
/ 03 февраля 2009

Не ясно, так как распределение не показано.

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

0 голосов
/ 03 февраля 2009

номер

Еще один совет - просто потому, что вы бежите по автостраде без удара, это тоже не делает это безопасным.

Какие указатели, по вашему мнению, вы используете повторно? Я не вижу ничего используемого после его освобождения, хотя я предполагаю, что readWords и countWords выделяют память. Если этого не произойдет, у вас возникнут еще большие проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...