문제

Firstly: I know that if the destructor of an object throws the behavior of the application cannot be counted on... The question is about memory issues.

So, now that this is clear:

See the app:

#include <stdlib.h>
#include <iostream>

class T
{
    public:
        T() : ma(0) 
             {std::cout << "T::T ->default<-" << std::endl; }
        T(const char* a) : ma(a) 
             {std::cout << "T::T ->" << ma << "<-" << std::endl; }
        ~T() 
             {std::cout << "T::~T ->" << ma << "<-" << std::endl; }

    private:
        const char* ma;
};

int main()
{
    T* t = new T();

    delete t;
}

and see it's valgrind output:

$ valgrind ./a.out
==29554== Memcheck, a memory error detector
==29554== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==29554== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==29554== Command: ./a.out
==29554== 
T::T ->default<-
T::~T ->==29554== 
==29554== HEAP SUMMARY:
==29554==     in use at exit: 0 bytes in 0 blocks
==29554==   total heap usage: 1 allocs, 1 frees, 4 bytes allocated
==29554== 
==29554== All heap blocks were freed -- no leaks are possible
==29554== 
==29554== For counts of detected and suppressed errors, rerun with: -v
==29554== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Explanation: T::~T ->==29554== tells me the destructor has encountered a dangerous sitation (std::cout took in a null value which is undefined) so the behaviour of the application is uncontrollable...

Since it does not print out the "<-" and it gives me the valgrind prompt immediately I expect it exited at that specific point. Valgrind does not report any segfault or something like that ...

But also, valgrind reports no memory leaks... and this is confusing me ... so what I think that happens is:

  1. I call delete t;
  2. the application frees the memory of t
  3. the destructor of t is called.

Can you please explain what is happening here?

Edit: To have a more clear question:

Is the destructor called on the freed memory or there is no undefined behaviour in the destructor when std::cout gets a null object?

도움이 되었습니까?

해결책

Undefined behaviour is undefined.

If I had to guess, it looks like, in this case, the stream detects the null pointer and goes into an error state, so you simply don't see any more output. The rest of the delete process apparently continues as expected.

Other forms of undefined behaviour, for example actually dereferencing a null pointer, might give different results. Likewise, other stream implementations may behave differently when you break their requirements.

다른 팁

Valgrind is right, there is no memory leak.

You allocated in the heap the Variable t but not the inner workings of the Class T. So the destructor has nothing to deallocate since you took the responsibility of deallocating the memory using delete.

You could allocate a variable inside Class T and not deallocating it in the destructor to see a memory leak.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top