问答 c++ 内存对齐问题

rywu · 2020年12月03日 · 最后由 rywu 回复于 2020年12月03日 · 2400 次阅读

补充 内存对齐的原则

1:数据成员对齐规则:结构 (struct)(或联合 (union)) 的数据成员,第一个数据成员放在 offset 为 0 的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始 (比如 int 在32位机为4字节,则要从4的整数倍地址开始存储。

2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a 里存有 struct b,b 里有 char,int ,double 等元素,那 b 应该从 8 的整数倍开始存储.)

3:收尾工作:结构体的总大小,也就是 sizeof 的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

问题背景

目前遇到一个问题,
CPerson cp;
CPerson2 cpp2;
有段代码 memcpy(&cp2,&cp,sizeof(cp)),目前在部分机器上 o0 、o3 编译 CPerson 、CPerson2,怀疑 sizeof 长度一致,导致 cp2 的 cc 数据可能被覆盖。

怀疑由于内存对齐导致的问题。但是 在 linux(x86-64 redhat)跟 window 下,使用不同的对齐的参数 2,4,8,16,均未测试出 相同.

咨询问题

继承后,结构体 是如何分配内存的 ,gcc o0,o3 对于内存分配的影响

备注

结构体 内容可能不是如下分布,供参考

struct CPerson {

    int a;//4
    char hh[3];//4
    double b; //8
    char hhs[3];// 3
    char l;         //  1
    char ps;         //1



};


struct CPerson2: public CPerson{

    char cc;//4
};

int main()
{
    printf("CPerson length:%d\n",sizeof(struct CPerson));

    printf("CPerson2 length: %d\n", sizeof(struct CPerson2));
}



如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 5 条回复 时间 点赞

c++ 对象永远别用 memcpy 进行内存拷贝,你不知道他对象里面的内存分布,person2 继承于 person1,编译器不同里面的对象分布情况也不同,memcpy 是给 c 用的,更别说上面那个是两个不同的类。

可以看一这个资料:https://docs.microsoft.com/en-us/cpp/cpp/trivial-standard-layout-and-pod-types?view=msvc-160
总的来说就是,C++ 语法规范里面对类和结构体的内存布局没有约定规范,但是 C++14 里面增加了几种特殊的情况对内存布局有约定。再具体到你这个场景,CPerson2 不符合 trivial/standard-layout 的要求,所以不能假定内存的布局。

rywu #3 · 2020年12月03日 Author
老张1024 回复

现在研发就 计划这么干,内存 copy(研发是直接内存取址方式),想 了解下 这样子的 在 gcc 和 vs 编译器下的内存模型,影响

另外如果不这么做,是派生类数据一个个赋值么。

rywu #4 · 2020年12月03日 Author
rihkddd 回复

恩恩,多谢!👍

rywu #5 · 2020年12月03日 Author

1:数据成员对齐规则:结构 (struct)(或联合 (union)) 的数据成员,第一个数据成员放在 offset 为 0 的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始 (比如 int 在32位机为4字节,则要从4的整数倍地址开始存储。
 
2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a 里存有 struct b,b 里有 char,int ,double 等元素,那 b 应该从 8 的整数倍开始存储.)
 
3:收尾工作:结构体的总大小,也就是 sizeof 的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册