类对象数组中的c ++内存

时间:2012-08-19 09:49:17

标签: c++ class memory layout member

我有一个这样的课程:

class Object {
public: 
    unsigned char data[8];
    // other variables
    // functions etc...
 };

问题是 - 对象成员是否都存储在相对于对象的内存中的相同位置?所以如果我有一个数组:Object array [3],给定一个char指针 char* data_ptr = array[0].data,将会 data_ptr + (sizeof(Object))然后始终指向数组[1] .data?

(我已经阅读了几个Q / As关于如何在类和结构的数据成员之间填充 - 但我不认为他们回答了我的问题。)

提前致谢, 本

5 个答案:

答案 0 :(得分:4)

sizeof Object已包含班级Object的所有内部填充。包括其末端的任何填充。数组不允许任何额外的填充。因此,data_ptr + sizeof Object的地址确实为array[1].data

然而我不确定这是否真的允许。也就是说,允许编译器 假设您从未将大于8的值(成员数组data的大小)添加到array[0].data,因此可能如果违反规则,则应用失败的优化。也就是说,您的代码可能实际上表现出未定义的行为(这是“在这种情况下允许编译器执行任何操作”的标准术语)。

然而,因为你使用指向char的指针,其中有更宽松的规则(你可以使用char*做很多事情,你不能用类型),无论如何它可能是它实际定义的行为。

答案 1 :(得分:2)

如果你的问题的目的是要了解记忆中的事物,那么这是可以接受的。

但如果您希望真正做到这一点:您想要做的事情对所有同事实际上是犯罪

在C ++中进行收集的正确方法不是使用数组,而是使用 std :: vector ,或者如果真的需要,则使用另一个std集合。我们不再使用C算术,而是通过迭代器访问矢量集合的项目。这就是C ++标准库的原因: - )

答案 2 :(得分:1)

我认为答案是“可能”,这意味着你不应该赌这个。最好的方法是在IDE调试器上查找内存地址。当您引入编译器可以优化的成员和方法时,您会发现这很容易被抛弃。例如,任何不访问可能静态的成员的常量或方法。例如:

void Object::doSomething() {std::cout << "something\n" << std::endl;}

我相信这实际上已经优化到静态分配中,因为我最近了解到,在((Object)NULL).doSomething();引入成员变量之前,这个Object实际上没有SEGFAULT。

答案 3 :(得分:1)

有许多因素决定了C ++中对象的大小。这些因素是: - 所有非静态数据成员的大小 - 数据成员的顺序 - 字节对齐或字节填充 - 其直接基类的大小 - 虚函数的存在(使用虚函数的动态多态)。 - 正在使用的编译器 - 继承模式(虚拟继承)

点击此处:http://www.cprogramming.com/tutorial/size_of_class_object.html

答案 4 :(得分:1)

是的,相对于对象基地址的布局将是常量。这是ABI的要求。对象和数组的任何间距或填充也由ABI指定。