我试图在我的程序中实现我自己的 c++ new & delete 运算符,如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <new>
using namespace std;
void *operator new(std::size_t size) throw(std::bad_alloc)
{
printf("My new is called!\n");
return malloc(size);
}
void operator delete(void *ptr) throw ()
{
printf("My delete is called!\n");
free(ptr);
}
void *operator new(std::size_t size, const std::nothrow_t&) throw()
{
return malloc(size);
}
void operator delete(void *ptr, const std::nothrow_t&) throw()
{
free(ptr);
}
void *operator new[](std::size_t size) throw(std::bad_alloc)
{
return malloc(size);
}
void operator delete[](void *ptr) throw ()
{
free(ptr);
}
void *operator new[](std::size_t size,
const std::nothrow_t&) throw()
{
return malloc(size);
}
void operator delete[](void *ptr,
const std::nothrow_t&) throw()
{
free(ptr);
}
class Object
{
public:
Object() {}
~Object() {}
private:
int a;
};
int main()
{
Object* obj = new Object();
if (obj)
delete obj;
return 0;
}
然后我发现,如果程序构建为: -- 一个 exe,那么我的 new/delete 会按预期调用 -- 但是,一个共享对象,那么 new & delete 的符号将被重新定位,所以在我的环境当它由 dlopen 在另一个程序中加载时,新的和删除的将被映射到另一个程序的新的和删除...
详细信息如下...
构建一个exe:
gcc -m32 -c main.cpp gcc -m32 main.o -o main.exe
$ ./main.exe 我的新被调用!我的删除被称为!
$ objdump -d main.exe 080484ac :
80484ac: 55 push %ebp
80484ad: 89 e5 mov %esp,%ebp
80484af: 53 push %ebx
80484b0: 83 ec 24 sub $0x24,%esp
80484b3: 83 e4 f0 和 $0xfffff0 ,%esp
80484b6: b8 00 00 00 00 mov $0x0,%eax
80484bb: 83 c0 0f 添加 $0xf,%eax
80484be: 83 c0 0f 添加 $0xf,%eax
80484c1: c1 e8 04 shr $0x4,%eax
80484c4 : c1 e0 04 shl $0x4,%eax
80484c7: 29 c4 sub %eax,%esp
80484c9: c7 04 24 04 00 00 00 movl $0x4,(%esp)
80484d0: e8 1f ff ff ff call 80483f4 <_Znwj> --> 新:预期!!
80484d5: 89 c3 mov %eax,%ebx
80484d7: 89 1c 24 mov %ebx,(%esp)
80484da: e8 35 00 00 00 调用 8048514 <_ZN6ObjectC1Ev>
80484df: 89 5d f8 mov %ebx,-0x8(%ebp)
80484e2: 83 7d f8 00 cmpl $0x0,-0x8(%ebp)
80484e6: 74 22 je 804850a
80484e8: 8b 45 f8 mov -0x8(%ebp),%eax
80484eb: 89 45 e8 mov %eax,-0x18(% ebp)
80484ee: 83 7d e8 00 cmpl $0x0,-0x18(%ebp)
80484f2: 74 16 je 804850a
80484f4: 8b 45 e8 mov -0x18(%ebp),%eax
80484f7: 89 04 24 mov %eax,(%esp)
80484fa: e8 1b 00 00 00 调用 804851a <_ZN8466ObjectD 804851a <_ZN8466ObjectD>
8451a <_ZNffObjectD e8 mov -0x18(%ebp),%eax
8048502: 89 04 24 mov %eax,(%esp)
8048505: e8 0a ff ff ff call 8048414 <_ZdlPv> --> 删除:预期构建一个共享对象:
gcc -m32 -c main.cpp gcc --shared -m32 main.o -o main.so
$ objdump -d main.so 000006d4 :
6d4: 55 push %ebp
6d5: 89 e5 mov %esp,%ebp
6d7: 53 push %ebx
6d8: 83 ec 24 sub $0x24,%esp
6db: 83 e4 f0 和 $0xffffffff0 ,%esp
6de: b8 00 00 00 00 mov $0x0,%eax
6e3: 83 c0 0f 添加 $0xf,%eax
6e6: 83 c0 0f 添加 $0xf,%eax
6e9: c1 e8 04 shr $0x4,%eax
6ec : c1 e0 04 shl $0x4,%eax
6ef: 29 c4 sub %eax,%esp
6f1: c7 04 24 04 00 00 00 movl $0x4,(%esp)
6f8: e8 fc ff ff ff call 6f9 ---> 新:要重新定位,意外 :(
6fd: 89 c3 mov %eax,%ebx
6ff: 89 1c 24 mov %ebx,(%esp)
702: e8 fc ff ff ff call 703
707: 89 5d f8 mov %ebx,-0x8(%ebp)
70a: 83 7d f8 00 cmpl $0x0,-0x8(%ebp) 70e
: 74 22 je 732
710: 8b 45 f8 mov -0x8(%ebp),%eax
713: 89 45 e8 mov %eax,-0x18(%ebp)
716: 83 7d e8 00 cmpl $0x0,-0x18(%ebp)
71a: 74 16 je 732
71c: 8b 45 e8 mov -0x18(%ebp),%eax
71f : 89 04 24 mov %eax,(%esp)
722: e8 fc ff ff ff call 723 ---> 删除:要重新定位,意外:(
727: 8b 45 e8 mov -0x18(%ebp),%eax
72a: 89 04 24 mov %eax,(%esp)
72d:e8 fc ff ff ff 调用 72e