Allocate and Delete memory for pointers in a struct C++

11,976

Solution 1

It would have to be

delete[] newObject->name;
delete newObject->test;
delete newObject;

because name was allocated with new[] while the other two were allocated with new. Neither delete nor delete[] changes the pointer value, though, it just invalidates what the pointer used to point to.

However, doing it this way is rather terribad. In the case of the object itself and the int, there is no reason to use dynamic allocation at all, and for name there's a class in the standard library called std::string that does the memory management for you. It would be best to replace the code with

#include <string>

struct Student {
  std::string name;
  int         test;
  float       gpa;
};

int main() {
  Student newObject;

  // do stuff, for example
  newObject.name = "John Doe";
  newObject.test = 123;
  newObject.gpa  = 3.1415926;

  // no manual cleanup necessary; it happens automatically when
  // newObject goes out of scope.
  return 0;
}

Solution 2

If you're using C++, you should use constructors, and destructors inside your structure(unless you REALLY need to have POD type structure).

struct Student
{
    Student(){
        name = new char[10];
        test = new int;
    }
    ~Student(){
        delete[] name;
        delete test;
    }
    char *     name;
    int  *     test;
    float      gpa;

};

int main() {
    Student *newObject = new Student;
    delete newObject;
    return 0;
}

Deletes on pointers inside struct will be called automatically when you use delete on newObject.

Keep in mind that using delete, does not delete any data! It just frees the used memory-says something like "Hey, I'm not using this part of memory anymore", so it can be used by some other data. You must always use delete, when you finished using some pointer, or you'll get memory leak.

Solution 3

The short answer is that you do need to use delete or delete [] (as appropriate) on each member pointer. As remyabel commented, delete does not change the value of the pointer, it simply deallocates the memory that that pointer was referring to.

// delete dynamically constructed members
delete newObject->test;
delete[] newObject->name;

The implementation of new may allocate memory in ways that are different for arrays of items than for single items, so it is important when deleting that you use delete [] for the former and delete for the later.

A more idiomatic way of handling clean-up is to perform these deletes in the destructor of the struct Student. The members are allocated and constructed, or initialized with null pointers at construction for safety (delete on a null pointer does nothing.)

struct Student
{
    char *   name;
    int  *   test;
    float    gpa;

    Student(): name(0), test(0), gpa(0.0f) {}

    ~Student() {
        delete[] name;
        delete test;
    }
};

delete newObject will then in turn delete the allocated members correctly, provided they were indeed allocated with new[] and new.

Because the destructor cannot guarantee that the members were indeed allocated this way, it is in turn best to pass the responsibility for allocating the members to member functions or constructors of the structure as well.

Solution 4

As said in comments, delete just frees the memory, it doesn't change the address pointed by the pointer. If you don't want to allocate / free the memory by yourself, prefer smart pointers.

Share:
11,976
ReeSSult
Author by

ReeSSult

Updated on June 05, 2022

Comments

  • ReeSSult
    ReeSSult almost 2 years

    Given the following struct declaration:

    struct Student
    
    {
    
       char *     name;
       int  *     test;
       float      gpa;
    
    };
    
    int main() {
    
    Student *newObject = new Student;
    
    newObject->name = new char[10];
    newObject->test = new int;
    
    return 0;
    }
    

    My question is how do I destroy the created dynamic variables ? I tried delete newObject->name; and delete newObject->test;but it doesn't seem to work because it shows me the same addresses as before delete . Is it just enought to delete the object by using delete newObject; newObject = nullptr;?

  • ReeSSult
    ReeSSult about 9 years
    Thank you . I am C++ student and I have to use cstrings and dynamic allocation for learning purposes. So I do 'cout << newObject; ' before and after 'delete newObject' and I get totally different values of memory addresses , but when I do it for 'delete newObject->test;' the values stay the same . Why ?
  • Wintermute
    Wintermute about 9 years
    Assuming that you mean, for example, that newObject->test changes after delete newObject, a number of things can have happened -- newObject->test is not a valid thing to use after newObject is deleted, and you cannot depend on it having any value. Among the things that could result in such a visible change: if you're working with Visual Studio, the debug heap's deallocation routine overwrites the deallocated memory with 0xfeeefeee to make it recognizable. Let me stress again that this is not dependable, and that code like that could crash or do any number of other things.