【发布时间】:2016-11-09 15:00:42
【问题描述】:
我正在编写一个可以在多个系统上运行的库(其中一些没有malloc 或stdlib)。在我的标准库(不同的库)中,我重写了new 和delete 运算符以对函数进行通用调用(此示例没有这些函数)。每个系统都会覆盖这些对其各自内存分配设备的通用调用。
问题是当我尝试这样做时。下面是一些简化的示例代码来重现该问题:
#include <cstdlib>
void* operator new(unsigned long size) {
return std::malloc(size); // would normally call an intermediate function which would be overridden by the system
}
void operator delete(void* object) {
std::free(object); // would normally call an intermediate function which would be overridden by the system
}
void operator delete(void* object, unsigned long size) {
std::free(object); // would normally call an intermediate function which would be overridden by the system
}
class MyClass {
};
int main() {
MyClass* myClass = new MyClass();
delete myClass;
}
当我使用纯 gcc-6(无参数)构建它并使用 valgrind(无参数)运行时,我收到此错误:
==11219== Mismatched free() / delete / delete []
==11219== at 0x4C2DD6B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11219== by 0x108730: operator delete(void*, unsigned long) (in /home/chris13524/tmp/test.o)
==11219== by 0x10875A: main (in /home/chris13524/tmp/test.o)
==11219== Address 0x5200040 is 0 bytes inside a block of size 1 alloc'd
==11219== at 0x4C2D1AF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11219== by 0x108745: main (in /home/chris13524/tmp/test.o)
看来delete 运算符工作正常,但 Valgrind 正在覆盖我已覆盖的 new 运算符。知道如何解决这个问题吗?
删除中间函数不是一个选项,因为我还有其他代码。
它如何在我的真实程序上运行的示例(同样,我的示例中没有显示):
new => create => <intermediate code> => createImpl => malloc
create => <intermediate code> => createImpl => malloc
我正在使用 gcc v6.2.0、valgrind v3.12.0 和 Ubuntu 16.10。
【问题讨论】:
-
我不是 C++ 大佬,但你的问题引起了我的注意。我观察到您的操作员函数的签名与您似乎试图覆盖的标准签名不匹配:
void* operator new ( std::size_t count )。参数类型会有所不同,或者至少可能会有所不同,具体取决于std::size_t解析到的内容。 -
@JohnBollinger 更改类型并不能解决问题。无论哪种方式,这都不是一个选项,因为某些系统没有
std::size_t。 -
再次检查您的重载运算符是否真的被调用(例如写一些东西来输出)。看起来它叫做内置的
operator new,但是你的替换operator delete,这显然是不匹配的。尝试使用和不使用 valgrind(以确定 valgrind 是否是罪魁祸首)。此外,提及您的编译器和版本,以及 valgrind 版本(和您的平台)可能会有所帮助。 -
@ComicSansMS 同样,也无法在 v5 上重现。我正在使用 gcc v6 来获得这个。
-
@rcmgleite 它还没有被打补丁 afaik,评论错误报告。
标签: c++ gcc valgrind new-operator gcc6