Могу ли я создать функцию «zap» в C ++, которая работает с указателем, если ему не выделена память? - PullRequest
2 голосов
/ 04 июня 2011

У меня есть функция zap (), написанная для освобождения 1-го массива следующим образом.

void zap(double *(&data))
{
    if (data != NULL)
    {
       delete [] data;
       data = NULL;
    }
    return;
}

У меня сложилось впечатление, что if data != NULL не будет пытаться освободить память, которая никогда не выделялась, но я думаю, что ошибаюсь. У меня возникла следующая проблема реализации.

void fun()
{
    int condition = 0;
    double *xvec;
    double *yvec;
    allocate_memory_using_new(yvec); //a function that allocates memory
    if (condition == 1) allocate_memory_using_new(xvec);
    //some code
    //deallocate memory:
    zap (yvec);
    zap (xvec); //doesn't work
    return;
}

Вывод следующий:

 Unhandled exception at 0x6b9e57aa (msvcr100d.dll) in IRASC.exe: 0xC0000005: Access
 violation reading location 0xccccccc0.

Так что я понимаю, что нежелательно пытаться вызывать zap, когда очевидно, что указатель никогда не использовался. Мне просто интересно, есть ли способ проверить адрес указателя в какой-то момент в функции zap (), чтобы избежать исключения. Заранее благодарим за помощь и понимание!

Ответы [ 4 ]

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

Указатели магически не инициализируются до 0, только когда они глобальные или статические. Вы должны сделать это:

double *xvec = NULL;
double *yvec = NULL;

Если нет, они содержат случайный мусор, который был оставлен в стеке, где они были созданы. И этот мусор большую часть времени не NULL.

Кроме того, вам не нужно проверять NULL, так как delete в этом случае не работает:

double* xvec = NULL;
delete xvec; // perfectly valid

Кроме того, если вы работаете с Visual Studio 2010, я рекомендую использовать nullptr вместо NULL.

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

Я пришел к выводу, что формы массивов new и delete квалифицируются как анти-паттерны C ++ - они кажутся разумными, но в действительности почти любое их использование в основном гарантированно приведет к большему горе и проблемы, чем полезный код.

Таким образом, я бы сказал, что попытка исправить вашу zap - это все равно, что найти женщину, которая только что была в огне и получила ожоги 3 й степени по меньшей мере на 85% ее тело, и пытается поправить ее, подстригая ноготь, который она сломала, убегая от огня.

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

В C ++ указатели не инициализируются автоматически в NULL, как в других языках (например, Java), поэтому значение xvec (указатель) не определено и может быть или не быть NULL при тестировании.

void fun()
{
    double *xvec; // value of xvec undefined, might be 0 or not
    // ...
    zap (xvec);   // if it is not 0, you will try to delete: Undefined Behavior
}

Простым решением является инициализация указателя в определении double *xvec = 0;. Кроме того, вам не нужно проверять NULL (или 0) в вашей функции zap, delete не вызовет неопределенного поведения при вызове по нулевому указателю:

template <typename T>
inline void zap( T *& p ) {
   delete p;
   p = 0;
}
0 голосов
/ 04 июня 2011

Значения xvec и yvec указывают на случайные числа, а не на NULL. Я думаю, что ваша функция allocate_memory не работает должным образом, так как обычно возвращает указатель на блок памяти, который вы бы присвоили xvec и yvec

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