空数组 《深度探索C++对象模型》上的一处变迁

前几天上网无意中看到一段程序,可以在VCdebug模式下面通过提取动态分配的内存前面的cookie得到具体分配了多少内存。以前我也想通过cookie来提取这个信息,但当时逐字节分析的,理不出头绪来

 

int i = *(int*)( (char*)p - 4 * sizeof( int ) );

 

当然这不具有通用性,在release模式下就不行了。

然后为它构造一个模板函数,用起来方便一点

 

template<typename T>

int getMemSize(T p)

{

 int i = *(int*)( (char*)p - 4 * sizeof( int ) );

 return i;

}

 

执行这段代码,这一直是我想干的。

 

    int *p = 0;

p = new int[0];

   cout<<getMemSize(p)<<endl;

 

本来期望输出1,因为lippman在《深度探索C++对象模型》上讲到了new的一种实现

 

 extern  void* operator new(size_t size)

{

   if(size == 0)

     size = 1;

   ……

}

 

如果传进去的size0,那么size会自动设为1。解释的原因是:每一次对new的调用都必须返回一个独一无二的指针,解决该问题的传统方法是传回一个指针,指向一个默认为1byte的内存块。

但上面的语句输出的是0p实际上分配的是零个内存单元。然后执行

cout<<(int)p<<endl;

这句,可以发现p实际上是一个指向了一个有效的内存地址。

在争论面前唯一能依赖的就只有标准了。2003的标准上这样写到:

 

When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements.

 

size0的时候将分配一个没有元素的数组。看来输出0是正确的。<<>>离出版到现在,已经10年了,或许这里已经发生了变迁。

但还有两个疑问,我猜测这里的p指向的地址应该是cookie的最后一个内存单元的下一内存单元,那么这样就应该可以得到一个独一无二的地址,那么当年为什么会单独分配一个lbyte的单元出来?

这种零元素数组有什么用?

另外在MFC中还使用了另外一种零元素数组。

 

class A

{

public:

     static  int a;

     static  int b[0];

     static  int c;

};

int A::a;

int A::b[];

int A::c;

 

int main()

{

     cout<<(int)(&A::a)<<endl;

     cout<<(int)(&A::b)<<endl;

     cout<<(int)(&A::c)<<endl;

}

 

这里ab的地址是相同的(如果你把b中的元素个改为一个大于0的数,就不相同了,前提是a,b,c在内存中是连续存放的,但没有理由让它们不连续存放: ) ),说明b的确是一个零元素的数组。

MFC的消息映射表中

 

static const AFX_MSGMAP_ENTRY _messageEntries[]

 

如果你没有定义消息映射,那么就为空

如果要添加消息映射项,可以像                                                    

int A::b[] = {1,2};

这样添加就行了;

### 回答1: 《深度探索C++对象模型》是由侯捷所著的一本经典的C++图书,该书于2012年由机械工业出版社出版。本书的主要内容涵盖了C++对象模型的深入解析和探讨。 在书中,作者详细讲解了C++中的对象模型和相关的概念,如类、对象、继承、多态等。作者首先介绍了C++对象模型的基本概念和特点,包括对象的内存布局、虚函数表和虚函数指针等。然后,作者深入探讨了C++中的继承机制和多态性,包括单继承、多继承、虚继承等。作者还详细介绍了虚函数的实现原理和使用方法。 在书中,作者对C++对象模型的实现细节进行了深入的剖析,包括成员变量和成员函数的内存布局、函数指针和成员函数指针的用法等。同时,作者还讨论了C++中的一些高级特性,如模板、内存管理和异常处理等。通过对C++对象模型深度探索,读者可以更好地理解C++的内部机制和原理,提高程序设计和开发能力。 《深度探索C++对象模型》适合具有一定的C++编程基础的读者阅读,尤其是对C++对象模型感兴趣的读者。通过阅读本书,读者可以进一步了解C++的底层实现和运行机制,从而提高自己的编程能力和代码质量。此外,本书还提供了大量的示例代码和实践案例,可以帮助读者更好地理解和应用所学知识。 总之,《深度探索C++对象模型》是一本深入探讨C++对象模型的经典著作,通过对C++的底层实现和内部机制的剖析,帮助读者深入理解C++编程语言,并提高自己的软件开发能力。 ### 回答2: 《深度探索C++对象模型》是由Stanley B. Lippman于1994年所著的一本经典畅销的C++书籍,该书详细介绍了C++对象模型的内部实现细节。 C++对象模型是指C++编译器在处理对象、继承、多态等面向对象特性时所采用的具体实现方式。这本书通过对对象模型的剖析,帮助读者深入理解C++的内部工作原理,从而写出更高效、更可靠的C++代码。 在《深度探索C++对象模型》中,作者首先介绍了对象、虚函数、继承等C++核心概念,然后详细讲解了C++对象模型的构建过程,包括对象布局、成员函数指针、虚函数表等。作者逐步深入地剖析了C++对象模型在内存中的表示方式,解释了为什么C++可以支持如此强大的面向对象特性。 此外,本书还探讨了一些高级主题,如多重继承、虚拟继承、构造函数和析构函数的执行顺序等。对于想要深入学习C++的读者来说,这本书提供了一些宝贵的技术手册和实用的经验。 尽管《深度探索C++对象模型》的出版时间是1994年,但它仍然被广泛认可为学习C++对象模型的经典之作。在2012年时,由于C++的发展和演进,也许一些内容已经有些过时,但很多基本概念和原理仍然适用。 总而言之,《深度探索C++对象模型》是一本值得阅读的C++经典著作,通过深度探索C++对象模型,读者可以更加深入地了解C++的内部工作原理和实现方式,提升自己的开发技能。 ### 回答3: 《深度探索C++对象模型》是一本于2012年出版的书籍。该书的作者Andrews和Sorkin以全面的角度深入探讨了C++对象模型。该书重点介绍了C++中的对象表示、虚函数、继承、多重继承、构造函数、析构函数等内容,以及与之相关的语法、原理和底层实现。 这本书为读者揭示了C++对象模型的奥秘,让人更加深入地理解C++语言中的类和对象。作者通过分析对象布局、虚函数表、虚函数调用、多继承中的数据布局和函数调用等等,解释了C++对象模型的实现机制。 在读者了解C++对象模型的基础上,该书还介绍了如何有效地利用对象模型来提高程序的性能。作者讨论了虚函数的成本以及如何减少虚函数调用的开销,提供了一些优化技巧。此外,书中还对C++的构造函数和析构函数进行了深入的讨论,详细解释了构造函数和析构函数的执行机制和注意事项。 总的来说,《深度探索C++对象模型》是一本深入剖析C++对象模型的重要参考书籍。通过阅读该书,读者可以更加全面地了解C++的类和对象的实现原理,对于理解C++语言的底层机制和优化程序性能具有积极的作用。无论是对于初学者还是有一定C++基础的开发人员来说,该书都是一本值得阅读的重要参考书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值