delete operator not working

Started by
6 comments, last by rip-off 13 years, 5 months ago
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.
Advertisement
The first code sample "works" because you don't access any member data in SomeClass::printHello().
As SiCrane has told you, you don't use member data in your function.

new and delete only allocates or frees space for data members.
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.
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).
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.
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.
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.

This topic is closed to new replies.

Advertisement