2

Considering the following:

tbModelHFrame = new TbModelHeaderFrame(this, storage->getDataBase());

I guess the correct way to delete tbModelHFrame memory will be

delete tbModelHFrame;

Right?

How do I check that the memory was really released?

KcFnMi
  • 5,516
  • 10
  • 62
  • 136
  • 2
    why do you need to check the memory is actually released? – demonplus Jul 07 '15 at 12:29
  • Call `delete` and trust your runtime library. – Bathsheba Jul 07 '15 at 12:31
  • Do you have any reason whatsoever to suspect that it *wasn't* released? Or do just not trust C++ runtime library implementors? – molbdnilo Jul 07 '15 at 12:38
  • What do you define as "released"? – cmannett85 Jul 07 '15 at 12:43
  • @ molbdnilo, Neither. Just came with the curiosity to check/confirm (learn) it. – KcFnMi Jul 07 '15 at 12:45
  • 2
    @KcFnMi, if you suspect a security issue (someone else accessing the released memory) you can ship your own allocator and override it with `\0`-bytes before releasing. – WorldSEnder Jul 07 '15 at 12:46
  • @WorldSEnder I think your own allocator would be overkill, but writing null bytes shoud alleviate any security problems. – OMGtechy Jul 07 '15 at 12:47
  • @ cmannett85, by "released" I was trying to mean free (not used any more). – KcFnMi Jul 07 '15 at 12:49
  • It's good to be cynical. I have a macro wrapping code such as i++ to check that the new value is actually one higher than it was before. You'd be horrified to learn how many times the cheeky compiler pulls a fast one! –  Jul 07 '15 at 12:52

4 Answers4

10

How do I check that the memory was really released?

You don't.

C++ has no means of telling whether a pointer points to a valid object or a random region in memory. The latter includes a region that was valid at some point, but has been deleted since.

It is up to the developer to organize their code in a way that this cannot happen.

The only guarantee that the language gives you to help you out here, is that a delete call never fails. So if you call delete once on the object, you can be reasonably sure that the object destroyed properly and the memory was released. Just don't attempt to access it again afterwards, or you'll be in trouble.

ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
2

Yes, what is allocated with new should be freed with delete. A way to check if every dinamically allocated memory has been freed is to use Valgrind's Memcheck

Anyway, it is usually safer to use smart pointers (See here).

Community
  • 1
  • 1
bznein
  • 908
  • 7
  • 21
  • 1
    Smart pointers are the way to ensure that delete is called, not that delete will release the memory – demonplus Jul 07 '15 at 12:35
  • you're right, I was referring to the first part of the question, but I should have specified it :) – bznein Jul 07 '15 at 12:39
1

According to the delete operator reference:

[..] In all cases, if ptr is a null pointer, the standard library deallocation functions do nothing.

If the pointer passed to the standard library deallocation function was not obtained from the corresponding standard library allocation function, the behavior is undefined.

After the standard library deallocation function returns, all pointers referring to any part of the deallocated storage become invalid.

Any use of a pointer that became invalid in this manner, even copying the pointer value into another variable, is undefined behavior. (until C++14)

Indirection through a pointer that became invalid in this manner and passing it to a deallocation function (double-delete) is undefined behavior. Any other use is implementation-defined.

Thus, in case of a problems of deleting the pointer, it is undefined behavior.

Community
  • 1
  • 1
vahancho
  • 20,808
  • 3
  • 47
  • 55
0

The premise of the question is wrong: if delete doesn't release the memory, your heap is corrupted and your application can already do anything, including formatting your hard drive. So you've got bigger problems than a mere delete being a no-op if it comes to that. So, don't worry about it. As long as haven't messed up your heap due to memory errors in your own code, you'll be fine.

In any case, you should not use naked pointers as owning pointers. This is C++, not C.

Use a smart pointer:

QScopedPointer<TbModelHeaderFrame> tbModelHFrame(
  new TbModelHeaderFrame(this, storage->getDataBase())
);
...
tbModelHFrame->something(); // do something with it

And that's it. The memory will be released when the pointer goes out of scope. You don't have to worry about it.

The pointer can also be a class member:

class Foo {
  QScopedPointer<TbModelHeaderFrame> m_modelHFrame;
  ...
};

Foo::Foo() :
  m_modelHFrame(new TbModelHeaderFrame(this, storage->getDataBase())) {
  ...
}

or

Foo::Foo() : ... {
  m_modelHFrame.reset(new TbModelHeaderFrame(this, storage->getDataBase()));

  ...
}

Modern C++ code should be designed to not to use manual memory management except where absolutely necessary for well understood reasons. In most cases, naked pointers and manual memory management in modern C++ are a sign of bad design, not necessity.

TL;DR: Modern C++/Qt code can and should read a bit like Python :)

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313