Release memory c ++ (delete)

2

I'm working with linked Lists (using pointers).

In a memory reserve function (using new) as long as% co_of% In another function I release all the memory (with delete) and according to the project statement I should be able to generate a Lista == NULL but after using delete List is different from NULL.

I exemplify it with the following code, where I ask for memory for a first node and then for the second iteration as nuevo_nodo I release the memory with delete, but for the third iteration the list is not equal to null, so I I wonder if I have to initialize List to NULL after using delete

#include <iostream>
#include <cstdlib>

using namespace std;

struct Nodo {
    int numero;
    Nodo *Siguiente;
};

int main(){
    Nodo *Lista = NULL;

    for (int i=0; i<3;i++){
        if( Lista==NULL ) {
            cout<<"\nAgregar nodo."<<endl;
            cout<<"Lista: "<<Lista<<endl;
            Lista= new Nodo;
            cout<<"Lista: "<<Lista<<endl;
        } else {
            cout<<"\nEliminar Nodo."<<endl;
            cout<<"Lista: "<<Lista<<endl;
            delete Lista;
            cout<<"Lista: "<<Lista<<endl;
        }

    }
    system("pause");
    return 0;
}

I wonder if you would have to manually initialize List in NULL even after using delete, and why does this happen?

    
asked by José F 23.11.2017 в 18:15
source

2 answers

2
  

I wonder if I would manually have to initialize it in NULL.

Yes. You must. Deleting a pointer does not put the pointer to null values.

As an analogy, imagine that the pointer is a plate and the node is spaghetti with Bolognese. When you eat the spaghetti the dish is dirty, you can use it again for another diner (another spaghetti node) putting spaghetti on the dirty dish (the other diner will not know) but if your rule is to serve only in clean dishes first you must clean it (put the plate at NULL ).

  

Why is this happening?

One of the C ++ mantras is " do not pay for what you do not use ", which is usually interpreted as " do not do things you do not know are strictly necessary " . Erasing the content of something pointed by a pointer and putting the pointer to NULL are two operations, the second being unnecessary because the pointer is usable whether it points to deleted data or points to NULL .

However, Bjarne Stroustrup (the creator of C ++) believes that it is a good idea that delete reset the pointers and regrets that this idea did not become popular, here is an excerpt from your website (my translation):

  

Let's consider

delete p;
// ...
delete p;
     

If the percentage ... does not change p the second delete p; is a serious error that C ++ can not protect effectively (without unusual precautions). Since deleting a null pointer is harmless by definition, a simple solution would be for delete p; to make p = 0; after doing whatever it takes. However, C ++ does not guarantee that.

     

One reason is that the operand of delete should not be a value on the left side, consider:

delete p+1;
delete f(x);
     

Here, the implementation of delete does not have a pointer to which you can assign zero. These examples may be rare, but they make it impossible to guarantee that "any pointer to an erased object is 0". A simple way to skip this rule is to have two pointers to an object:

T* p = new T;
T* q = p;
delete p;
delete q;   // caramba!
     

C ++ explicitly allows implementations of delete to zero a left value operand, and I hoped that implementations would do so, but this idea does not seem to have become popular among implementers.

Other things to consider.

  • Use nullptr instead of NULL : The macro NULL is simply the value 0, this can lead to confusing pointers with integers in some overloads, if you use the null pointer literal ( nullptr ) you will avoid that possible problem.
  • Use pre-increment instead of post-increment .

    li>
answered by 24.11.2017 / 08:44
source
0
  

after using delete List is different from NULL.

Yes, that's right; the operator delete of the standard library frees the previously assigned memory with new , and leaves the pointer in an invalid state (should not be used under penalty of undefined behavior "). And as you have noticed, it will not assign nullptr (the NULL for pointers in C ++).

So, your example could look like:

#include <iostream>
// #include <cstdlib>
using namespace std;

struct Nodo {
    int numero;
    Nodo *Siguiente;
};

int main()
{
    Nodo *Lista = nullptr; // es un NULL específicO para punteros.

    for (int i = 0; i<3; i++) {
        if (Lista == nullptr) {  // 
            cout << "\nAgregar nodo.\n";
            cout << "Lista: " << Lista << '\n';
            Lista = new Nodo;
            cout << "Lista: " << Lista << '\n';
        }
        else {
            cout << "\nEliminar Nodo.\n";
            cout << "Lista: " << Lista << '\n';
            delete Lista;
            cout << "Lista: " << Lista << '\n'; // ahora lo ves
            Lista = nullptr;
            cout << "Lista: " << Lista << '\n'; // ahora no lo ves
        }

    }
    //system("pause"); // disculpa, siento un rechazo 
                       // físico por esta cosa
    return 0;
}

(I also removed those terrible << endl; )

    
answered by 25.11.2017 в 17:35