4

As I understand, the following code is a perfectly fine way to create a QObject

QLabel *label = new QLabel("label");
QWidget window;
label->setParent(&window);
window.show();

As I am reading everywhere "the parent takes ownership of the newly created object - and eventually calls delete", or "the composite object takes ownership of the children so, as long as the parenting has been done, you can be assured that the child QObjects will be destroyed when the parent is destroyed" (from How does Qt delete objects ? And what is the best way to store QObjects?)

Can someone tell me how can Qt "take ownership" of a QObject? More technically: how is it possible for Qt (which is a library and has its own runtime) to call operator delete on a pointer I created with an operator new from a different runtime? Why doesn't it crash?

EDIT

I am adding this reference as the whole point of the question comes from this:

"The code running in the DLL might be using a different C++ runtime library, which means that the layout of the heap will be different. The DLL might be using a different heap altogether.

Calling delete (in the main program) on a pointer allocated by the DLL (or vice versa) will lead to (at best) an immediate crash or (at worst) memory corruption that'll take a while to track down." (from C++ mix new/delete between libs?)

user815129
  • 2,050
  • 1
  • 17
  • 29
  • 4
    You are probably trying too hard. :-) The Qt code will do a `delete label;`, just like your code could do. No difference, no magic involved. – Bo Persson Jun 07 '18 at 08:35
  • but the Qt's delete operator is different from mine, since a library gets its own new/delete operators which should not be mixed The code running in the DLL might be using a different C++ runtime library, which means that the layout of the heap will be different. The DLL might be using a different heap altogether. – user815129 Jun 07 '18 at 08:38
  • The new part of the question is about something else. If you mix DLLs randomly, like some Debug mode and some Release mode, or using different compilers, you *will* get problems. But if everything is compiled with the same compiler using the same settings, everything will use the same language runtime. And then there are no problems. – Bo Persson Jun 07 '18 at 08:56
  • You have to be using a Qt kit that is compiled with the same compiler you are using, so (at least on windows), we have different kits representing the same version of Qt but compiled with different compilers... – Mike Jun 07 '18 at 08:57
  • I had the wrong assumptions that there could be multiple heap managements even using the same compiler, version or configuration. Thanks – user815129 Jun 07 '18 at 09:00

2 Answers2

4

Let the source code speak instead of mere answers. Here is what QObject's internals do:

for (int i = 0; i < children.count(); ++i) {
    currentChildBeingDeleted = children.at(i);
    children[i] = 0;
    delete currentChildBeingDeleted;
}
children.clear();

Function with the code above is called in destructor. So, it is pretty simple. Parent stores pointers to all of its children. When parent's destructor is being called, it deletes all it's children. This is recursive, as calling delete on object calls its destructor

Why Qt can safely delete without concerns about runtime library

Actually, due to name mangling, exporting C++ interface nearly forces You to use the same version of compiler and runtime library. This in very crude way allows Qt to assume that delete is safe to call.

Community
  • 1
  • 1
bartop
  • 8,927
  • 1
  • 18
  • 46
1

for Qt (which is a library and has its own runtime)

This is where your assumption is wrong. Firstly, there is no such thing as "runtime" for the OS. "Runtime" is an informational term.

Modern operating systems have things like: binary executable, shared libraries aka dynamically linked libraries aka DLL, static libraries, processes, threads, etc.

In this case, your executable and the Qt shared library are loaded into the SAME process, which means the memory is shared among them. That means your executable can see Qt memory and conversely Qt can see your memory.

dimm
  • 1,563
  • 9
  • 14
  • I updated the question to make it more clear. thanks – user815129 Jun 07 '18 at 08:43
  • 2
    @user815129 This is true for C-interface. When creating interface through C++ You actually have to have same runtime as name mangling is/may be different even for different versions of same compiler. – bartop Jun 07 '18 at 08:47
  • Have you considered the case where your code and Qt use the same standard library? – dimm Jun 07 '18 at 08:49
  • since I dont compile qt from the source, nor include qt sources, I tought I can't be sure ..of course I am wrong on some assumptions, since the given example is absolutely correct – user815129 Jun 07 '18 at 08:52