Solved

Memory allocation (properly deleting a structure)

Posted on 2008-06-23
16
223 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
Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

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

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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 …
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org Go to that link and select download selenium in the right hand columnThat will then direct you to their download page.From that page s…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

778 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