выделить память и перед удалением выделить определить NULL - PullRequest
3 голосов
/ 26 августа 2011

Я хотел бы спросить, правильно ли я следующее:

MyClass *obj = new MyClass();//allocate memory

obj.Variab="HELLO";

obj=NULL;
delete obj; //free memory

Удалена ли память, выделенная для obj, после двух последних предложений?Appreciate.THX Я хотел бы отметить, что я работаю в C ++ / Ubuntu.G ++ - это компилятор

РЕДАКТИРОВАТЬ:

Что если у меня есть?

int i=0;
list<string>l;
while (i<100)
{  
    MyClass *obj = new MyClass();//allocate memory
    obj->Variab="HELLO";
    //add the obj.valie in a list 
    l.push_back(obj);
    i=i+1;

delete obj; //free memory

}

все в порядке?

Ответы [ 5 ]

4 голосов
/ 26 августа 2011

Это не правильно:

obj = NULL; // don't do that! 
delete obj;

Когда вы присваиваете NULL для obj, вы теряете адрес, который он содержал раньше, утечка памяти . Когда вы затем delete obj, вы удаляете NULL, что является четко определенным - как , ничего не делая .
Как говорили другие,

delete obj;
obj = NULL;

- это общий шаблон для этого.

Однако я считаю это анти-паттерном .

  1. Всякий раз, когда у вас возникает желание назначить NULL указателю после удаления его содержимого, спросите себя: Почему этот указатель все еще находится в области видимости? Вы уверены, что вы все еще нужно?
    Намного лучше просто позволить указателю выпасть из области видимости, как только это будет сделано.

  2. Всякий раз, когда вы делаете

    resource r = acquire();
    use(r);
    free(r);
    

    (при том, что память / динамически распределяемые объекты являются наиболее распространенным ресурсом), должны прозвучать сигналы тревоги. Что делать, если use(r) терпит неудачу с исключением?
    Никогда не используйте голые, тупые указатели. Лучше читать о RAII и интеллектуальных указателях .

4 голосов
/ 26 августа 2011

нет, вы должны использовать delete перед присвоением NULL

delete obj; //free memory 
obj=NULL;

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


ваш вопрос для редактирования:

этот код не будет компилироваться, так как obj не определен вне области действия while, в любом случае также l является list<string>, и вы пытаетесь вставить типы MyClass*, это приведет к еще одна ошибка компиляции. также вы должны использовать obj->Variab, а не obj.Variab, так как obj является указателем.

РЕДАКТИРОВАТЬ, чтобы РЕДАКТИРОВАТЬ:

хорошо, вы все еще получили ошибку компиляции, так как obj не определено, когда вы пытаетесь delete это. попробуйте это:

#include <iostream>
#include <list>
using namespace std;
class MyClass {
public:
    string Variab;
};

void myfunction (const string& s) {
  cout << " " << s;
}

int main()
{
    int i=0;
    list<string>l;
    while (i<100) {
        MyClass *obj = new MyClass();//allocate memory
        obj->Variab="HELLO";
        l.push_back(obj->Variab);
        i=i+1;
        delete obj; //free memory
    }
    for_each (l.begin(), l.end(), myfunction);

}
2 голосов
/ 26 августа 2011

Это приведет к утечке, delete не очистит то, что вы выделили с new.Изменить порядок:

delete obj;
obj = NULL;  // I would avoid this.
0 голосов
/ 26 августа 2011

Вы должны delete тот же адрес, который был возвращен new - поэтому вам нужно сначала delete, а затем установить значение NULL.

Установка указателя на ноль не влияет на распределение - вы просто перезаписываете адрес, сохраненный в указателе, и больше не можете получить доступ к объекту (что означает, что вы не можете delete объект и получить его утечку).*

0 голосов
/ 26 августа 2011

Установка obj на null не освобождает выделенную память.Память больше не назначается переменной, но все еще зарезервирована, что приводит к утечке памяти.Вызов delete для нулевого указателя не будет иметь никакого эффекта.После освобождения памяти указатель становится недействительным, и рекомендуется назначить его null.Вам необходимо изменить порядок последних 2 операторов:

delete obj; //free memory first
obj=NULL; //Set pointer to null for safety
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...