• Advertisement
Sign in to follow this  

C++ delete operator, where can I get more specific info.

This topic is 4248 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've just been browsing a bunch of tutorials on new and delete and they all say the same basic thing, delete for objects, delete [] for arrays... But in reality its not that simple (at least for me, maybe I'm missing something - kinda the point of this post). Every time I write or update a program I have to spend hours trial and error hacking away trying to stop it giving me 'ASSERT_DEBUG_FAILED' this and 'User Breakpoint' that, not to mention the classic 'Access Violation' -- whenever I do cleanup. Most annoyingly, the use of delete [] is a mystery to me beyond very simple dynamic arrays of built-in types. Half the time I try to delete an array I get an error, and if I remove the delete [] statement I get memory leaks. Bit of a rant... Basically I was just wondering if anyone has links to any more in depth tutorials/reference material -- or could even explain the low-level process here, if its fairly straightforward. Cheers,

Share this post


Link to post
Share on other sites
Advertisement
Well, i hope you're not trying to delete[] static arrays!
basicaly here's how it works:

// Note: although this example uses int in all cases,
// but it's the same with any type (including user structs and classes)
int main()
{
int static_var = 5; // cleaned up automaticaly
int static_arr[2] = {0, 1}; // cleaned up automaticaly
int *dynamic_var = new int (1); // must delete
delete dynamic_var; dynamic_var = 0; // don't forget to assign 0 (or NULL) after you delete
int *dynamic_arr = new int [static_var]; // must delete[]
delete[] dynamic_arr; dynamic_arr = 0; // again - don't forget to assign 0
return 0;
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Could it be that you are modifying stuff outside of the allocated memory? I think that when you new or new[] something, a 'memory reminder-header' is also saved before or after the memory area, so that the delete know how much to deallocate. If you happen to write outside of your allocated memory, you might maybe mess up the data in that header. I also know that there is a 'no mans land' sort of area before and after the allocated memory. if you change anything in that area, it will be detected when you deallocate with delete.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Could it be that you are modifying stuff outside of the allocated memory? I think that when you new or new[] something, a 'memory reminder-header' is also saved before or after the memory area, so that the delete know how much to deallocate. If you happen to write outside of your allocated memory, you might maybe mess up the data in that header. I also know that there is a 'no mans land' sort of area before and after the allocated memory. if you change anything in that area, it will be detected when you deallocate with delete.

Share this post


Link to post
Share on other sites
Anonymous Poster: Unlikely I'm writing outside of bounds, since the errors I'm getting (*tend to get in every program I write*) are on closure of the program, i.e. final cleanup -- and the rest of the program works up until then.

Paulius Maruska: OK, I know most of that. My problems seem to come when I've got arrays of objects, rather than primitive types...

Eg.

array Obj* objs = new Obj[x];
objs[i(for all i)] = new Obj();
delete objs[i(for all i)];
delete [] objs;
-- This sort of setup tends to give me headaches.

What is the value of setting to NULL? Can you use that to test if something has already been deleted?


Share this post


Link to post
Share on other sites
Quote:
Original post by DangerDave
array Obj* objs = new Obj[x];
objs[i(for all i)] = new Obj();
delete objs[i(for all i)];
delete [] objs;

That's wrong. And won't compile, give us your actual code or we will have to guess what you are doing wrong.

All you need is:
Obj* objs = new Obj[x];
delete [] objs;

Share this post


Link to post
Share on other sites
Quote:
Original post by Trap
Quote:
Original post by DangerDave
array Obj* objs = new Obj[x];
objs[i(for all i)] = new Obj();
delete objs[i(for all i)];
delete [] objs;

That's wrong. And won't compile, give us your actual code or we will have to guess what you are doing wrong.

All you need is:
Obj* objs = new Obj[x];
delete [] objs;



No particular code (well, lots, too much), just general info right now..

Ah OK, sorry, I mean:

Obj** objs = new Obj*[x];
objs = new Obj();

With what you mentioned, no (or maybe only default) constructor is called...

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Could it be that you are modifying stuff outside of the allocated memory? I think that when you new or new[] something, a 'memory reminder-header' is also saved before or after the memory area, so that the delete know how much to deallocate. If you happen to write outside of your allocated memory, you might maybe mess up the data in that header. I also know that there is a 'no mans land' sort of area before and after the allocated memory. if you change anything in that area, it will be detected when you deallocate with delete.


This is true in debug mode when you use VC++ - I don't know if it is still true for other compilers, but it sounds logical.

The other valid reason to get this kind of errors is to (for example) allocate an array in a DLL and delete [] it in the DLL caller. The DLL and the application may not use the same runtime - depending on the compilation options.

Regards,

Share this post


Link to post
Share on other sites
Quote:
Original post by DangerDave
Anonymous Poster: Unlikely I'm writing outside of bounds, since the errors I'm getting (*tend to get in every program I write*) are on closure of the program, i.e. final cleanup -- and the rest of the program works up until then.

Paulius Maruska: OK, I know most of that. My problems seem to come when I've got arrays of objects, rather than primitive types...

Eg.

array Obj* objs = new Obj[x];
objs[i(for all i)] = new Obj();
delete objs[i(for all i)];
delete [] objs;
-- This sort of setup tends to give me headaches.

What is the value of setting to NULL? Can you use that to test if something has already been deleted?


NULL is the only value that can't be returned by new (or new[]). Thus, initializing an object pointer to NULL means that it is not valid. It is also an idiomatic notation to say either "I didn't created this" or "I deleted this" or "this is not valid at all". Setting your pointer to NULL after you deleted it will also protect you from double deletion because delete (or delete[]) will test if the pointer is a NULL value before deleting it.

Regards,

Share this post


Link to post
Share on other sites
Quote:
Original post by Emmanuel Deloget
Setting your pointer to NULL after you deleted it will also protect you from double deletion because delete (or delete[]) will test if the pointer is a NULL value before deleting it.

Regards,


Ah VERY useful, so I can freely attempt to delete the same object twice, as long as the pointer is set to NULL after the initial delete? And I wont get any crashes?

Share this post


Link to post
Share on other sites
Quote:
Original post by DangerDave
Anonymous Poster: Unlikely I'm writing outside of bounds, since the errors I'm getting (*tend to get in every program I write*) are on closure of the program, i.e. final cleanup -- and the rest of the program works up until then.


Sounds like you delete a block of memory multiple times then. Check your program for that. You're not allowed to delete memory that hasn't been allocated (or has already been deleted once)

One quick and dirty fix would be to set any pointer to 0 (null) after you've deleted them. Then you won't get errors if you accidentally delete them again afterwards. The "proper" solution is to just know what's been deleted and what haven't, so you delete each allocation exactly once. [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by DangerDave
Ah VERY useful, so I can freely attempt to delete the same object twice, as long as the pointer is set to NULL after the initial delete? And I wont get any crashes?


Yes (but see the big BUT below), as long as you do it throught the same pointer. Obviously, if you have multiple pointers pointing to the same object, setting one of them to NULL does nothing to prevent accidental re-deletion through another pointer. This is where smart pointers come in handy.

BUT: trying to avoid double deletes by setting pointers to NULL only cures the symptom, not the disease. In some ways, it is even worse than letting the program crash — double deletions imply that your design is not logically sound, and instead of hiding the problem you should strive to design so that double deletions are not allowed to happen in the first place. Again, smart pointers are useful here.

Share this post


Link to post
Share on other sites
Quote:
Original post by DangerDave
Ah VERY useful, so I can freely attempt to delete the same object twice, as long as the pointer is set to NULL after the initial delete? And I wont get any crashes?


(1) Yes, passing a null pointer to the delete operator is okay.

(2) No, setting a deleted pointer to null will give you false confidence. If you have two pointers to the same object and you delete and null one of them, your program will crash somewhere after the double deletion, usually the next time you try to new or delete something else.

This is where all the talk about smart pointers comes in to play. Either structure your code to use std::auto_pointer (you will need to think about move semantics) or use boost or tr1 refcounter pointers. My most successful practice is the avoid ever having to use delete -- and I write a lot of code every day.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement