ReeSSult
ReeSSult

Reputation: 496

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

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;?

Upvotes: 2

Views: 13543

Answers (4)

Sebastian Kuczyński
Sebastian Kuczyński

Reputation: 170

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.

Upvotes: 4

halfflat
halfflat

Reputation: 1584

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.

Upvotes: 2

Wintermute
Wintermute

Reputation: 44043

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;
}

Upvotes: 3

vincentp
vincentp

Reputation: 1433

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.

Upvotes: 1

Related Questions