gpt4 book ai didi

c++ - MinGW 中的全局重载运算符 new/delete

转载 作者:行者123 更新时间:2023-12-02 10:24:43 25 4
gpt4 key购买 nike

我想在我的应用程序中重载新/删除运算符以捕获所有内存泄漏。它在 Linux 上运行良好。但是我在 Windows 上遇到了问题。新/删除重载仅适用于 .exe,但不适用于来自 .dll 文件的调用。此外,如果在我的代码中创建了某个对象但从 .dll 文件中删除它会导致应用程序崩溃。引用 here

Versions (1-8) are replaceable: a user-provided non-member function with the same signature defined anywhere in the program, in any source file, replaces the default version. Its declaration does not need to be visible.



我编写了最小的 Qt 模板应用程序来测试它。这里 mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <cstdio>
#include <cstdlib>

// replacement of a minimal set of functions:
void *operator new(std::size_t sz)
{
void *ptr = std::malloc(sz);
std::printf("global op new called, size = %zu, pointer = 0x%p\n", sz, ptr);
return ptr;
}

void operator delete(void* ptr) noexcept
{
std::printf("global op delete called, pointer = 0x%p\n", ptr);
std::free(ptr);
}

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

MainWindow::~MainWindow()
{
delete ui;
}

输出:
global op new called, size = 20, pointer = 0x00c4f608
global op new called, size = 24, pointer = 0x00c4f648
global op new called, size = 16, pointer = 0x00b35bf8
global op new called, size = 24, pointer = 0x00c4f6a8
global op new called, size = 24, pointer = 0x00c4f868
global op new called, size = 24, pointer = 0x00c4f988
global op delete called, pointer = 0x00c4f608

它使用 Qt 4.8.7/GCC 4.8.2 和 Qt 5.5.1/GCC 4.9.2 进行了测试。那么如何在 MinGW 中全局重载 new/delete 呢?

P.S. 我写的最少 test case重现问题。它输出我
$ ./main.exe
global op new called, size = 4, pointer = 0x003e17b8
global op new called, size = 4, pointer = 0x003e3d68
library delete called, pointer = 0x003e17b8
global op delete called, pointer = 0x003e3d68

最佳答案

我在 GCC Bugzilla 上找到了答案 – Bug 77726 .

刘昊写道:

It isn't weired if you know how a Dynamic-Link Library (DLL) on Windows works different than a Shared Object (SO) on Linux.

Windows does not have a dynamic linker such as ld.so on Linux. Symbols in a DLL are resolved at build-time, in contrary to Linux, where symbols in a SO are resolved at load-time. The DLL loader can resolve symbols to addresses, but it isn't as powerful as linkers after all. Consequently, an executable cannot use its strong symbols to override already-resolved weak ones in a DLL.

If the user does not define a sized deallocation function, the default one in libstdc++*.dll is used, which calls the weak, default, non-sized deallocation function in the same DLL, which is the only candidate when the DLL is built and can't be overridden.

关于c++ - MinGW 中的全局重载运算符 new/delete,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46025819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com