Sign in to follow this  
Masanori

delete operator not working

Recommended Posts

Masanori    100
Hello,

This is perfectly working and I cant figure out why:

#include <iostream>
#include <string>

class SomeClass
{
public:
void printHello()
{
std::cout << "hello" << std::endl;
}
};

int main()
{
SomeClass *myClass = new SomeClass;
delete myClass;
myClass->printHello();

return 0;
}




I'm expecting a segfault or at least that nothing is actualy printed on the screen, but everything just work as not intended...

However this do segfault:


#include <iostream>
#include <string>

int main()
{
std::string *myString = new std::string("hey there");
delete myString;
std::cout << *myString << std::endl;

return 0;
}




Basicly if I allocate a class of my own and delete it, it is not deleted, when sl or stl class are.

Im running g++ 4.5.1 on linux.

Any idea? Thank you.

Share this post


Link to post
Share on other sites
Masanori    100
Ok, I though a class had a memory adress by "itself".

But I tryed this and it still works XD:


#include <iostream>
#include <string>

class SomeClass
{
public:
void printInteger()
{
m_integer = 20;
std::cout << m_integer << std::endl;
}

private:
int m_integer;
};

int main()
{
SomeClass *myClass = new SomeClass;
delete myClass;
myClass->printInteger();

return 0;
}




m_integer isnt freed for some reason...

It is allocated on the stack so it shall be freed after the destructor call?![totally][totally][totally]

What am I not understanding?

Thanks.

Share this post


Link to post
Share on other sites
rip-off    10976
Firstly, what is happening here is undefined behaviour. This means that literally anything can happen when you run the code, even apparently correct/reasonable behaviour

In your latest example, the allocator has requested memory from the OS, but as an optimisation it does not immediately release it when you called delete, figuring that most applications will have a fresh memory request coming in pretty soon (that and it has probably allocated some memory in that page anyway, preventing it from being released yet).

This means that nothing has really happened except that the allocator has marked the memory (somewhere in its internal data) as "available for allocation". If you had a thread running in the background, or inserted another function call, you might find the memory has been overwritten because some other part of your program is now using it.

This is where you get memory corruption, hat memory you wrote to could potentially be used by unrelated data.

And you didn't allocate on the stack in your latest program. Both new/delete control the heap (or the free store, which is almost the same thing really, just one is managed by malloc/free and the other by new/delete).

Share this post


Link to post
Share on other sites
SiCrane    11839
Now what your function is doing is taking a random memory address, writing to it and then immediately reading from it. Things to try: 1) setting the member variable in the constructor and then reading in the function. 2) changing the member variable type from an int to a more complex type with invariants like a std::string.

Share this post


Link to post
Share on other sites
Masanori    100
Quote:
And you didn't allocate on the stack in your latest program. Both new/delete control the heap (or the free store, which is almost the same thing really, just one is managed by malloc/free and the other by new/delete).


I meant "m_integer" has been allocated on the stack

Thank you for the explanation, compiler should really give a warning or something cause I think this kind of behavior can lead to subtile bugs...

Anyway thank you all for the clarification.

Share this post


Link to post
Share on other sites
rip-off    10976
m_integer is allocated where the enclosing SomeClass instance is allocated, here this is the heap.
Quote:

Thank you for the explanation, compiler should really give a warning or something cause I think this kind of behavior can lead to subtile bugs...

Certainly that would be nice. But this is deemed too expensive, this is the cost of using a low level language.

On the bright side, by consistently using RAII objects, standard containers and smart pointers you can all but eliminate manual memory management (or at least contain it to a small part of your code). This reduces the scope for such bugs.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this