Using new operator with objects always needed

Started by
11 comments, last by rip-off 12 years, 7 months ago
Let's say I allocate memory with operator new for an array of objects in another object in C++. Let's say that I need this array available at all times. Do I need to use delete at all? The object I am declaring this array of objects in is the base of my program, it is always on and will never close until the program is closed. Do I need to make a destructor that frees that memory?
Advertisement
Sounds related to another recent discussion. Opinions vary. Personally, I sleep better at night if I'm cleaning up data before the program terminates. I think it keeps the bogeymen at bay.

Let's say I allocate memory with operator new for an array of objects in another object in C++. Let's say that I need this array available at all times. Do I need to use delete at all? The object I am declaring this array of objects in is the base of my program, it is always on and will never close until the program is closed. Do I need to make a destructor that frees that memory?


Strictly speaking, on a modern OS you don't "have to" delete objects that should last for the full duration. (On WinME and older the user will have to reboot the system eventually if you do this)

However, it is far easier to track down memory leaks if you do try to delete everything (There are automated tools that can help you with this and having them warn you of memory leaks you don't care about makes it harder to filter out the ones you do care about), also, as you are allocating an array of objects in another object the practice of relying on the OS to clean the mess up also means that you will get serious memory leaks if you decide to use the class in a different way.

Basically relying on the OS to remove the negative effects of your bugs can make those bugs irrelevant for the end user, but adding bugs to your software on purpose with the motivation that "The OS most users are using will remove the effects of these bugs anyway" is just silly.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

Let's say I allocate memory with operator new for an array of objects in another object in C++.


If you just use a std::vector instead, the entire point is moot. Any time you are using new directly, it is always a sign that you should consider the alternatives.
There are non-memory resources to consider. Think about if one of these objects, directly or indirectly, had an open file handle with some application buffered data. If it is not correctly disposed of, this data will be lost, even though the OS will flush its buffers and close the file handle.

As SimonForsman says, it makes your program brittle because if you starting moving the code around later, you might end up with a real memory leak. E.g. if some of this code is moved into an area that should be setup and torn down as you transition different levels.

Aardvajk's point is important too - disciplined use of RAII has benefits far beyond ensuring resources are de-allocated correctly. It also leads to less code that is easier to change and maintain.

These are some good reasons for de-allocation. What are your reasons against de-allocating the memory? I hope this isn't premature optimisation...

These are some good reasons for de-allocation. What are your reasons against de-allocating the memory? I hope this isn't premature optimisation...


I have an unload function which deletes all my rendering resources at the closure of the program.

I tried putting delete [] arrayofobjects[x] for the array of objects I used new with in there and I got a BLOCK TYPE IS VALID error.
I read that this happens when something is deleted twice. So doesn't that mean the delete statement is unneeded?

Again this array of objects is always needed. There is too much unnecessary overhead in filling it up with information more than once. I do this on program load and keep it around.

I tried putting delete [] arrayofobjects[x] for the array of objects I used new with in there and I got a BLOCK TYPE IS VALID error.
I read that this happens when something is deleted twice. So doesn't that mean the delete statement is unneeded?

So your argument against de-allocation is because you got an error that you don't know how to fix? I'm not sure that's a good reason. The problem could be from memory corruption which IS a bug that SHOULD be fixed. If you can't explain how you're deleting that memory twice then you must assume the problem is more severe until you actually know what's going on.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!


I tried putting delete [] arrayofobjects[x] for the array of objects I used new with in there and I got a BLOCK TYPE IS VALID error.
[/quote]
How is the array allocated?

You should generally be calling it like so: delete [] arrayofobjects. If each element of the array is individually allocated with new (should it be?) you'll also need to loop like so:

int numObjects = /* ... */;

// Setup
ExampleClass **arrayofobjects = new ExampleClass *[numObjects];
for(int i = 0 ; i < numObjects ; ++i)
{
arrayofobjects = new ExampleClass(/* ... */);
}

// Run game ...

// Teardown
for(int i = 0 ; i < numObject ; ++i)
{
delete arrayofobjects;
}
delete [] arrayofobjects;

I cannot recommend using std::vector<> higher, it will save you lots of headaches for this kind of thing. Also avoid allocating each individual object unless you have a very good reason.
As noted repeatedly in Iatent's thread, properly cleaning up your arrays (via delete[] or using std::vectors) will prevent "false" positives in your leak detection tools when trying to find another memory leak that is, say, leaking fast enough to crash your program.

If the goal is faster code, you might consider skipping cleanup in release mode.
If the goal is easier code to write, it'll unfortunately only be counter-productive in the long run.


I tried putting delete [] arrayofobjects[x] for the array of objects I used new with in there and I got a BLOCK TYPE IS VALID error.

How is the array allocated?

You should generally be calling it like so: delete [] arrayofobjects. If each element of the array is individually allocated with new (should it be?) you'll also need to loop like so:

int numObjects = /* ... */;

// Setup
ExampleClass **arrayofobjects = new ExampleClass *[numObjects];
for(int i = 0 ; i < numObjects ; ++i)
{
arrayofobjects = new ExampleClass(/* ... */);
}

// Run game ...

// Teardown
for(int i = 0 ; i < numObject ; ++i)
{
delete arrayofobjects;
}
delete [] arrayofobjects;

I cannot recommend using std::vector<> higher, it will save you lots of headaches for this kind of thing. Also avoid allocating each individual object unless you have a very good reason.
[/quote]

Yes I was using delete []. I switched to using a vector instead.

This topic is closed to new replies.

Advertisement