关于'eh vector constructor/destructor iterator'的讨论及类的内存分布模型
[原理分析] 在用IDA反汇编C++程序的时候,经常会看到这样的语句:“call eh vector constructor iterator”或“eh vector destructor iterator”。 第一反应:这是在调用某个std::vector对象的构造函数或析构函数。但进一步的阅读发现跟std::vector的实现对不上号,就是说程序中并没有声明std::vector对象。 其实,这是调用new或delete导致的,即 T * tt = new T[100]; delete [] tt; 其中,T是自定义类,并且自定义了构造函数或析构函数。 说到这里估计有人就会恍然大悟了。道理就是这么简单! “eh vector constructor/destructor iterator”按字面上理解,就是:数组-构造-迭代器或数组-析构-迭代器。 它发生在创建一个自定义类的数组时,C++在分配内存后自动迭代调用类的构造函数以初始化每一个数组元素,或析构。 但,这里有一个问题:new的时候知道数组的大小,但是delete的时候没有指定数组个数,那么C++是怎么知道对多少个对象调用析构函数,并且释放多大内存呢? C++程序员大概都有这样的疑问。 答案就是C++在创建数组的时候,在分配内存的头四个字节保存数组大小,从第4个字节开始才是数组内容,返回的时候也是返回的第4个字节之后的内存,所以导致大家感觉不到数组长度。 下面以一个简单的程序示范一下数组的创建过程、销毁过程、类的构造和析构、对象的内存分布模型,编译器是VC6.0,相信很多人都是在windows上搞反汇编的。 [示范程序] class demo_B { public: demo_B(); ~demo_B(); void set_value(int a, float b); private: int a_; float f_; }; demo_B::demo_B() { a_ = 1; f_ = -1.0; } demo_B::~demo_B() { a_ = -1; f_ = 0.0; } void demo_B::set_value(int a, float b) { a_ = a; f_ = b; } void test_foo(int n) { demo_B * buffer = new demo_B[n]; delete [] buffer; } int main(int argc, char const *argv[]) { test_foo(10); return 0; } 关键函数void test_foo(int n);用IDA反汇编如下: ...