先上代码:
#include <stdio.h> #include <malloc.h> class Test { private: #define MAX_NUM 2 public: Test() { printf("sizeof(Fct)=%d/n", sizeof(Fct)); printf("sizeof(&Test::Action1)=%d/n", sizeof(&Test::Action1)); printf("sizeof(&Test::Action2)=%d/n", sizeof(&Test::Action2)); int i; //Init Action Action = new Fct*[MAX_NUM]; for(i = 0; i < MAX_NUM; i++) { Action[i] = new Fct[MAX_NUM]; } Action[0][0] = 0; Action[0][1] = &Test::Action1; Action[1][0] = 0; Action[1][1] = &Test::Action2; } virtual ~Test() { int i; for(i = 0; i < MAX_NUM; i++) { if(Action[i] != 0) { delete [] Action[i]; Action[i] = 0; } } delete [] Action; Action = 0; } private: typedef void (Test::*Fct)(int); Fct** Action; void Action1(int x) { } void Action2(int y) { } }; int main(int argc, char* argv[]) { Test tt; return 0; }
这段代码在析构函数时会抛出类似下面的错误:
DAMAGE:after Normal block (#73) at 0x003D1818
网上很多文章都说到这是内存越界或内存分配不足引起的。奇怪,将Fct换成char类型,一切OK。
最后在前面加如下代码,重载new,delete运算符
void* operator new(size_t sz) { printf("operator new: %d Bytes/n", sz); void* m = malloc(sz); if(!m) puts("out of memory"); return m; } void* operator new[](size_t sz) { printf("operator new[]: %d Bytes/n", sz); void* m = malloc(sz); if(!m) puts("out of memory"); return m; } void operator delete(void* m) { puts("operator delete"); free(m); } void operator delete[](void* m) { puts("operator delete[]"); free(m); }
打印如下:
sizeof(Fct)=4
sizeof(&Test::Action1)=4
sizeof(&Test::Action2)=4
operator new[]: 8 Bytes
operator new[]: 0 Bytes
operator new[]: 0 Bytes
operator delete[]
Fct大小居然是0, 然而sizeof(Fct)=4,怪哉。更改Fct返回类型后发现,实际在new的时候Fct的大小是返回值的大小,void为0,int为4。
将
Action[i] = new Fct[MAX_NUM];
改为
Action[i] = (Fct*)new char[MAX_NUM * 4];
一切OK。内存大小分配正确。