PDA

View Full Version : [SOLVED] Uh oes! Have I been doing something wrong for a very long time? (C++)




chrono1081
May 22, 2011, 05:00 AM
Correct me if I'm wrong (PLEASE) but I thought this was the correct way to delete objects....(In C++)

Monster *newMonster = new Monster();


newMonster->whatever

delete newMonster;


Is this incorrect? If so how do I delete it the correct way? I've been doing this for years....:confused:



gnasher729
May 22, 2011, 05:16 AM
Correct me if I'm wrong (PLEASE) but I thought this was the correct way to delete objects....(In C++)

Monster *newMonster = new Monster();


newMonster->whatever

delete newMonster;


Is this incorrect? If so how do I delete it the correct way? I've been doing this for years....:confused:

Absolutely fine. What makes you think this would be wrong? I think you should give some more context here.

chrono1081
May 22, 2011, 05:31 AM
Absolutely fine. What makes you think this would be wrong? I think you should give some more context here.

I thought it was fine but two people in my one class told me I was wrong. (I didn't really trust them since I know I know more then they do when it comes to programming.) I also searched through my books and didn't see anything saying that was the wrong way to destroy objects but I wanted to ask just to be safe. They were very adamant about it being incorrect which caused me to double guess myself (even though they couldn't explain WHY it was incorrect).

The context really is as simple as that, I simply was making a place holder for the real monster class (which another team writes).
Thank you for your response :) I'll mark my thread as solved.

Cromulent
May 22, 2011, 06:12 AM
I thought it was fine but two people in my one class told me I was wrong. (I didn't really trust them since I know I know more then they do when it comes to programming.) I also searched through my books and didn't see anything saying that was the wrong way to destroy objects but I wanted to ask just to be safe. They were very adamant about it being incorrect which caused me to double guess myself (even though they couldn't explain WHY it was incorrect).

The context really is as simple as that, I simply was making a place holder for the real monster class (which another team writes).
Thank you for your response :) I'll mark my thread as solved.

new and delete in C++ are like malloc and free in C. Every new must have a corresponding delete otherwise you'll have a memory leak. The only time this isn't the case as far as I know is when you create a class on the stack in C++. In which case the class is automatically deallocated for you when it goes out of scope. Although having said that stack based class creation does not even use the new operator so the rule still holds.

ShortCutMan
May 22, 2011, 07:06 AM
Seems fine to me. As long as you are also using 'delete[] x' for deleting arrays that were allocated on the heap.

Also, here is a tip that I find many people don't know about so if you don't it will be helpful: you can perform delete on a NULL pointer and it will just no-op. So no need to do these ones that I see in some places:
if (x)
{
delete x;
}
This is defined by the standard so is multi-platform safe too.

jiminaus
May 22, 2011, 09:26 AM
Also, here is a tip that I find many people don't know about so if you don't it will be helpful: you can perform delete on a NULL pointer and it will just no-op. So no need to do these ones that I see in some places:
if (x)
{
delete x;
}
This is defined by the standard so is multi-platform safe too.

Will you look at that? I've always guarded a delete in case it was NULL. I'll stop doing that, thanks.

I think the OP's friends were confused about stack- verses heap-allocated objects. For example, the following is wrong:

Monster newMonster; // Stack-allocated, newMonster not a pointer
newMonster.whatever();
// delete newMonster; // I don't think this will compile
delete &newMonster; // and might need this to compile


Taking the address in order to delete something is a strange thing to do. I started to feel queazy just writing this code.

jtara
May 22, 2011, 01:29 PM
I thought it was fine but two people in my one class told me I was wrong.

And did they tell you how to do it RIGHT?

The only thing I can think of to do different is that it's a good idea to then set the pointer to NULL so that it's no longer pointing to the former memory location of the discarded object. It removes some temptation, because this will often work - for a while, until the memory is re-used. If you NULL it, you will get an exception if you try to use the pointer again. If you don't you might or might not.

From Wikipedia (Why don't people just check there first? While it may not always provide the best answer, it nearly always provides *an* answer, and usually a pretty good start...):

After calling delete the memory object pointed to is invalid and should no longer be used. Many programmers assign 0 (null pointer) to pointers after using delete to help minimize programming errors. Note, however, that deleting a null pointer has no effect (if the deallocation function is one supplied in the standard library[2]), so it is not necessary to check for a null pointer before calling delete.

MarkCollette
May 22, 2011, 03:00 PM
Kind of makes you wonder why delete wasn't designed to just null it out for you.

ncl
May 22, 2011, 04:20 PM
new and delete in C++ are like malloc and free in C. Every new must have a corresponding delete otherwise you'll have a memory leak. The only time this isn't the case as far as I know is when you create a class on the stack in C++. In which case the class is automatically deallocated for you when it goes out of scope. Although having said that stack based class creation does not even use the new operator so the rule still holds.
There is the placement new.
Kind of makes you wonder why delete wasn't designed to just null it out for you.
Because nothing guarantees that delete's argument will be an lvalue (eg: delete p+42).

chrono1081
May 22, 2011, 05:43 PM
Thank you guys for all of the responses :) The response I ended up getting back from the classmates were that "It just looked wrong". So it wasn't, they just thought it was and made me second guess myself.

I did learn some stuff from this thread though. I'm familiar with C++ and use it almost daily but I am by no means an expert and have plenty to brush up on (like when to allocate from the stack or heap, I'm not too familiar with when to use one or the other) so tips like these really help.

mfram
May 22, 2011, 11:42 PM
I'm familiar with C++ and use it almost daily but I am by no means an expert and have plenty to brush up on (like when to allocate from the stack or heap, I'm not too familiar with when to use one or the other) so tips like these really help.

The biggest difference between data allocated on the stack and data allocated on the heap is the data's lifetime. When your function returns, all data on the stack is destroyed and deallocated. Therefore, if you want your function to create some data that will be used by another part of your program, you generally have to use the heap. Stack memory is used for data you only use within your function and doesn't need to stay around after your function exits.

There are a couple disadvantages of using the heap. The biggest one is that you need to keep track of the memory and eventually deallocate it. Also, in some cases using the heap may be slower if the memory starts to get fragmented.

Another reason you may be forced to use the heap is because stack space is limited in some architectures. If you need a large buffer to store some data, or if you are making a lot of recursive calls you could run out of stack space eventually.

Summary:

- Stack: data used only within your function
- Heap: data that must live on after your function exits.

gnasher729
May 23, 2011, 05:09 AM
Taking the address in order to delete something is a strange thing to do. I started to feel queazy just writing this code.

"delete &newMonster" was badly wrong because newMonster was allocated on the stack, and delete will try to deallocate it from the heap; in addition delete calls the destructor, and the destructor would be called again when newMonster leaves its scope.

But just to confuse/enlighten you:

void strange_but_correct_delete (Monster& myMonster)
{
delete &myMonster;
}

int main (void)
{
Monster* myMonster = new Monster ();
strange_but_correct_delete (*myMonster);
}

This is correct because the strange function actually deletes an object on the heap.

chrono1081
May 24, 2011, 01:09 AM
"delete &newMonster" was badly wrong because newMonster was allocated on the stack, and delete will try to deallocate it from the heap; in addition delete calls the destructor, and the destructor would be called again when newMonster leaves its scope.

But just to confuse/enlighten you:

void strange_but_correct_delete (Monster& myMonster)
{
delete &myMonster;
}

int main (void)
{
Monster* myMonster = new Monster ();
strange_but_correct_delete (*myMonster);
}

This is correct because the strange function actually deletes an object on the heap.

Thanks so much for the tip!

MarkCollette
May 24, 2011, 11:38 AM
Because nothing guarantees that delete's argument will be an lvalue (eg: delete p+42).

I know they can't just make delete do that, they way it is designed, which is why I wonder why they didn't create it differently. Maybe something like use operator overloading to have a variant of delete that takes a reference to a pointer, or a pointer to a pointer, or something.