Редактирование аргумента функции c ++ - PullRequest
1 голос
/ 11 июня 2011

я делаю функцию выделения / освобождения памяти
это просто

inline void safedealloc ( void *mem )
{
     if ( mem ) { free( mem ); mem = NULL; }
}  

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

safedealloc( (char *)name );
safedealloc( (char *)name );

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

PS: name правильнораспределяется с использованием malloc с допустимым размером и содержимым

Ответы [ 4 ]

7 голосов
/ 11 июня 2011

Это почти наверняка не работает нормально, это бессмысленно, и в C ++ способ распределения памяти - это новый и удаление, а не malloc и свободный.Нет необходимости проверять наличие пустого указателя (NULL), который четко определен как в C, так и в C ++.И ваше присвоение NULL параметру функции ничего не делает - оно только изменяет параметр, а не его значение обратно в вызывающей программе.

И, наконец, если вы обнаружите, что пишете такой код:

char * p = malloc(100);
safefree( p );
safefree( p );

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

5 голосов
/ 11 июня 2011

mem = NULL; ничего не делает, , потому что mem - это другая переменная .

Попробуйте вместо этого (обратите внимание на & перед mem, что означает ссылку на mem):

template<typename T> //I added this due to request, since this doesn't quite work
                     //with pointers other than void*
inline void safedealloc ( T *& mem )
{
     if ( mem ) { free( mem ); mem = NULL; }
}

Является ли это действительно хорошей идеей или нет - это совершенно другой вопрос.
Ответ Нет . Зачем? Потому что, если вы допустили эту ошибку здесь, скорее всего, вы сделали такую ​​же ошибку в другом месте, и проблема просто начинается заново, за исключением того, что на этот раз она выше в стеке и ее труднее найти.

0 голосов
/ 11 июня 2011

Вы передаете указатель по значению, вот в чем проблема. Передайте указатель на указатель или ссылку на указатель, тогда ваше назначение будет работать.

0 голосов
/ 11 июня 2011

Вы пытаетесь изменить адрес внутри mem, но это работает только с локальным аргументом.

Вы передаете указатель по значению, что означает, что вы не можете изменить значение переменной, которую имеет вызывающий объект.

...