Solved

Memory allocation (properly deleting a structure)

Posted on 2008-06-23
16
221 Views
Last Modified: 2013-12-14
What would be the proper way to delete a structure?

I hear that if you are not careful in C++, you can delete a pointer to a variable and not the variable itself, which might lead to memory leaks and problems.

Have a look at the code snippet please.

1) IIs way #1 enough to properly clean the memory, or should I delete the individual variables first before deleting the structure?
2) How does destructors come into play with this, how do I use them... ~Test(). On this question I might be confusing structures with classes, or destructors with memory cleanup?

#include <cstdlib>

#include <iostream>
 

using namespace std;
 

	struct Test { 

	  char* data; 

	  int index; 

	  Test* nextStruct; 

	}; 
 

int main(int argc, char *argv[])

{
 

 	Test *x4 = new Test;

 	x4->data = "test";

 	x4->index = 0;

 	x4->nextStruct = NULL;
 

// delete variables, way #1

	delete x4;
 

// delete variables, way #2

	delete x4->data;

	delete x4->index;

	delete x4->nextStruct;

	delete x4;

}

Open in new window

0
Comment
Question by:codeQuantum
  • 8
  • 7
16 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 450 total points
ID: 21847513
The proper way in your example would be a plain

delete x4;

Deleting the variables inside the struct would only make sense if you allocated them via 'new' also. 'index' isn't even a pointer and 'data' a string literal that cannot be deleted. 'nextStruct', being NULL in your example would cause no harm, yet I am not sure if you really want to delete it...
0
 
LVL 5

Author Comment

by:codeQuantum
ID: 21847574
True, it did not compile. I had to change :

delete x4->index;
for
delete &x4->index;

I did not get an error on data. What is the problem?

This code is just an example. In my real code i need to create structures dynamically (a random number of structs with random values) and I need to write a function that does the cleanup after and frees the memory.
0
 
LVL 5

Author Comment

by:codeQuantum
ID: 21847595
Could you also clear my confusion about destructors with an explanation?

In other words, should I use a normal function for memory cleanup, or is it better to use a destructor ~Test() with the struct? an example would be helpful.
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 450 total points
ID: 21847610
The problem is that the struct members are not holding any memory that has been allocated via 'new' - thus 'delete' will fail at run-time, causing your program to terminate abnormally. There is no need to 'delete' the members unless the memory was allocated dynamically also. Calling 'delete' on the enclosing struct will do the job and take care of them. The situation would be different if you allocated 'data' differently, e.g. in the following
#include <cstdlib>

#include <iostream>

 

using namespace std;

 

        struct Test { 

          char* data; 

          int index; 

          Test* nextStruct; 

        }; 

 

int main(int argc, char *argv[])

{

 

        Test *x4 = new Test;

        x4->data = new char[42];

        x4->index = 0;

        x4->nextStruct = NULL;

 

        delete x4->data; // dispose the member...

        delete x4; // ... then the struct

}

Open in new window

0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 450 total points
ID: 21847637
>>is it better to use a destructor ~Test() with the struct?

That would be a better idea. Yet the restriction to only 'delete' memory that was allocated using 'new' still applies. You could do that ina constructor, e.g.
#include <cstdlib>

#include <iostream>

 

using namespace std;

 

        struct Test { 
 

          Test() {
 

            data = new char[42];

          }
 

          ~Test() {
 

            delete [] data;

          }
 

          char* data; 

          int index; 

          Test* nextStruct; 

        }; 

 

int main(int argc, char *argv[])

{

 

        Test *x4 = new Test;

        x4->index = 0;

        x4->nextStruct = NULL;

 

        delete x4; // ... then the struct

}

Open in new window

0
 
LVL 5

Author Comment

by:codeQuantum
ID: 21847742
Why did you declare a destructor, then still used //delete x4; at the end?

Or does delete trigger the destructor automatically?

(I am a beginner in C++)
0
 
LVL 86

Expert Comment

by:jkr
ID: 21847882
Well, the destructor is invoked when 'delete' is called for dynamically allocated structures, not automatically. That wit will happen only when you declare the variable as a 'regular' one, not as a pointer and being created via 'new'.
0
 
LVL 86

Expert Comment

by:jkr
ID: 21847889
BTW, see also http://www.cplusplus.com/doc/tutorial/dynamic.html ("Dynamic Memory")
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 5

Author Comment

by:codeQuantum
ID: 21848183
hahaha... I did not really understand your last post and I was reading that article just now. (before you posted the link.)

So if I am getting this right : destructors are not meant to be called manually like other functions but they are triggered by delete. For that to happen, I need to use new on the variables inside the structure (or is it the structure itself that should be dynamically allocated?) and those variables should not be pointers like nextStruct in my example.

Is that correct?
0
 
LVL 5

Author Comment

by:codeQuantum
ID: 21848241
Is there a function in C++ that let us test if a variable has been dynamically allocated or not?

I want to modify my destructor with conditional statements before the delete so it works in all cases.
0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 50 total points
ID: 21848283
>> Is there a function in C++ that let us test if a variable has been dynamically allocated or not?
Short answer, no.

You might find this a useful read...
"Requiring or prohibiting heap-based objects"
http://www.ishiboo.com/~nirva/c++/eff/MEC/MI27_FR.HTM
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 450 total points
ID: 21848566
>>destructors are not meant to be called manually like other functions but they
>>are triggered by delete

Either by a 'delete' or by the object going out of scope.

BTW, since you are allocating the variables via 'new', you *do* know which ones were allocated dynamically - you wrote the code that does it...
0
 
LVL 5

Author Comment

by:codeQuantum
ID: 21848838
You mean I should make the constructor use new for all variables to make sure?

But what if I use x4->data... That would not go through the constructor and I will have a problem?
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 450 total points
ID: 21849626
No, only for the ones that need to be dynamically allocated. Alternatively, initialize them to NULL and later delete them in the destructor if they are changed, e.g.
#include <cstdlib>

#include <iostream>

 

using namespace std;

 

        struct Test { 

 

          Test() {

 

            data = NULL

          }

 

          ~Test() {

 

            if (data != NULL) delete [] data;

          }

 

          char* data; 

          int index; 

          Test* nextStruct; 

        }; 

 

int main(int argc, char *argv[])

{

 

        Test *x4 = new Test;

        x4->index = 0;

        x4->data = new char[42];

        x4->nextStruct = NULL;

 

        delete x4; 

}

Open in new window

0
 
LVL 5

Author Comment

by:codeQuantum
ID: 21849777
Ok I think I am getting there. 2 details :

1) Since you only used the string in the constructor, does that mean integers and pointers don`t need to be dynamically allocated?
2) And what if I do something like :

Test *x3 = new Test{"string", 4, x2};

It won`t be affected by the constructor giving NUL values, right?

(by the way I doubled the points for this question)
0
 
LVL 5

Author Comment

by:codeQuantum
ID: 21852649
Worked out the details Thanks for your invaluable help, jkr!
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now