Re[5]: Любой программный продукт портят студенты и индусы
От: alzt  
Дата: 22.06.11 08:33
Оценка:
Здравствуйте, nizle, Вы писали:

N>>>>
N>>>>//file a.cpp
N>>>>void foo();
N>>>>{
N>>>>   CTLVParser* parser1 = NULL;
N>>>>   function( parser1 );
N>>>>   delete parser1;
N>>>>}

N>>>>//file b.cpp (реализация этой function)
N>>>>void function( CTLVParser* parser2 )
N>>>>{
N>>>>   parser2 = new CTLVParser();

N>>>>   ....
N>>>>}
N>>>>


A>>Только в данном случае будет утечка, т.к. "delete parser" вызовется для нуля.


N>Не будет утечки, этот указатель передается в функцию, там по этому адресу положат не ноль.


Я немного подправил исходный код. Что происходит. В первой строчке создаётся указатель parser1, который имеет значение NULL и некий адрес, пусть, например 0x..01.
Далее вызывается функция function, при этом ей передаётся параметр parser1, который имеет значение NULL и адрес 0x..01. При вызове функции происходит копирование значений параметров. В данном случае скопируется NULL. Адрес parser1 копироваться не будет, т.к. мы передаём не &parser1, а просто parser1.
Т.е. на входе функция function имеет параметр parser2 со значением NULL. Естественно этот параметр тоже где-то расположен и имеет некий адрес, например 0x..22.
Далее создаётся новый экземпляр CTLVParser, результатом операции new будет новый указатель, имеющий значение {new CTLVParser()}, это значение и будет записано в ячейку памяти parser2. Т.е. теперь parser2 имеет ненулевое значение. Но напомню, что parser2 — это всего лишь локальная переменная, находящаяся по адресу 0x..22, которая ничего не знает о переменной parser1 (адрес 0x..01). При завершении функции адрес 0x..22 станет недоступен, а память утечёт.
После вызова функции удаляется память, расположенная в ячейке parser1. Т.к. там лежал NULL и никто его не менял, то delete просто проигнорирует это значение.

Исправить код можно, если вместо CTLVParser* принимать на вход CTLVParser**. Тогда функция сможет получить тот самый заветный адрес 0x..01 и возможно, что-то туда сохранит.

Кстати, замечу, что подобная ситуация будет и в Java и в C#.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.