c++ memory in array of class objects

2019-06-23 15:02发布

I have a class like this:

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

The question is - are the object members all stored in the same place in memory relative to the object? So if I have an array: Object array[3], given a char pointer char* data_ptr = array[0].data, will data_ptr + (sizeof(Object)) then always point to array[1].data?

(I've read a couple of Q/As about how there might be padding inbetween data members of classes and structs - but I don't think they answer my question.)

Thanks in advance, Ben

5条回答
地球回转人心会变
2楼-- · 2019-06-23 15:22

sizeof Object already includes all internal padding of the class Object. including any padding at its end. Arrays don't allow any additional padding. Therefore it is true that data_ptr + sizeof Object will have the address of array[1].data.

However I'm not sure if this is actually allowed. That is, the compiler might be allowed to assume that you never add a value larger than 8 (the size of the member array data) to array[0].data, and therefore it might apply optimizations that fail if you violate the rules. That is, your code might actually exhibit undefined behavior (which is the standard term for "the compiler is allowed to do anything in this case").

However since you are using a pointer to char, for which there are more permissive rules (you can do many things with char* which you could not do with general types), it may be that it's actually defined behaviour anyway.

查看更多
欢心
3楼-- · 2019-06-23 15:34

If the aim of your question is to understand how things are in memory, then it is acceptable.

But if you want to do that for real: What you want to do is actually criminal against all your colleagues.

The proper way to go through collection in C++ is not to use an array, but an std::vector, or another std collection if it is really needed. We shouuld no longer use C arithmetics, but access the items of the vector collection through an iterator. That's the reason of the C++ standard library :-)

查看更多
Lonely孤独者°
4楼-- · 2019-06-23 15:34

There are many factors that decide the size of an object of a class in C++. These factors are: - Size of all non-static data members - Order of data members - Byte alignment or byte padding - Size of its immediate base class - The existence of virtual function(s) (Dynamic polymorphism using virtual functions). - Compiler being used - Mode of inheritance (virtual inheritance)

check here: http://www.cprogramming.com/tutorial/size_of_class_object.html

查看更多
beautiful°
5楼-- · 2019-06-23 15:37

I think the answer is "Maybe", which means you should not bet on this. Best way would be to play around on your IDE debugger looking up memory addresses. You'll find this could easily get thrown off when you introduce having members and methods that the compiler can optimize. For example any constants or a method that doesn't access any members that could be static. Ex:

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

I believe this actually gets optimized into the static allocation because I recently learned that this ((Object)NULL).doSomething(); actually works without a SEGFAULT until you introduce a member variable for Object.

查看更多
ゆ 、 Hurt°
6楼-- · 2019-06-23 15:40

Yes, the layout relative to the object's base address will be constant. This is a requirement for the ABI. Any spacing or padding of objects and arrays is also specified by the ABI.

查看更多
登录 后发表回答