Solved

Memory allocation (properly deleting a structure)

Posted on 2008-06-23
16
225 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

730 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