关于字节对齐不同导致的初始化异常问题

moonk-z 2017-12-07 11:55:34
在一个较大工程中。
有kps_data.h 定义一个较大的功能性struct
节选部分可能有问题的:

short peeked;
char pointset[MAXLEN];
char path[MAXLEN];
char ctrlmes[MAXLEN];;

多个kpsfunc1.cpp、kpsfunc2.cpp、kpsfunc3.cpp类调用到这个kps_data.h,通过#pragma pack(show)发现,在多个文档中调用到这个kps_data.h时,字节对齐有的是1有的是8.
接着,在进行初始化的时候发现,进行如下操作时

kps->ctrlmes[0] = '\0';
kps->path[0] = '\0';
kps->partsend = 0;

执行结束后,kps->ctrlmes[0]-kps->ctrlmes[7]内存并未进行初始化,而kps->ctrlmes[8] = ‘\0’,意味着,初始化时编译器找到的地址不是成员变量的实际地址。

由于kps_data.h属于公共类,不方便进行修改,而我的kpsfunc3.cpp、相关.h均已设置了#pragma pack(push,1)和#pragma pack(pop),但是还是无法正常初始化,请问这种情况我应该从何下手,谢谢!
...全文
273 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
moonk-z 2017-12-11
  • 打赏
  • 举报
回复
几天一直登不上csdn,已解决。问题还是出在字节对齐。 仔细翻了一下,由于func是通过某个BASE类继承kps_data.h的,但在另外一个业务层cpp直接使用了kps_data.h,导致两个调用的字节对齐不同,修正后就可以了。
赵4老师 2017-12-08
  • 打赏
  • 举报
回复
仅供参考:
#include <stdio.h>
#define field_offset(s,f) (int)(&(((struct s *)(0))->f))
struct AD  { int a; char b[13]; double c;};
#pragma pack(push)
#pragma pack(1)
struct A1  { int a; char b[13]; double c;};
#pragma pack(2)
struct A2  { int a; char b[13]; double c;};
#pragma pack(4)
struct A4  { int a; char b[13]; double c;};
#pragma pack(8)
struct A8  { int a; char b[13]; double c;};
#pragma pack(16)
struct A16 { int a; char b[13]; double c;};
#pragma pack(pop)
int main() {
    printf("AD.a %d\n",field_offset(AD,a));
    printf("AD.b %d\n",field_offset(AD,b));
    printf("AD.c %d\n",field_offset(AD,c));
    printf("AD sizeof %d\n", sizeof(AD));
    printf("\n");
    printf("A1.a %d\n",field_offset(A1,a));
    printf("A1.b %d\n",field_offset(A1,b));
    printf("A1.c %d\n",field_offset(A1,c));
    printf("A1 sizeof %d\n", sizeof(A1));
    printf("\n");
    printf("A2.a %d\n",field_offset(A2,a));
    printf("A2.b %d\n",field_offset(A2,b));
    printf("A2.c %d\n",field_offset(A2,c));
    printf("A2 sizeof %d\n", sizeof(A2));
    printf("\n");
    printf("A4.a %d\n",field_offset(A4,a));
    printf("A4.b %d\n",field_offset(A4,b));
    printf("A4.c %d\n",field_offset(A4,c));
    printf("A4 sizeof %d\n", sizeof(A4));
    printf("\n");
    printf("A8.a %d\n",field_offset(A8,a));
    printf("A8.b %d\n",field_offset(A8,b));
    printf("A8.c %d\n",field_offset(A8,c));
    printf("A8 sizeof %d\n", sizeof(A8));
    printf("\n");
    printf("A16.a %d\n",field_offset(A16,a));
    printf("A16.b %d\n",field_offset(A16,b));
    printf("A16.c %d\n",field_offset(A16,c));
    printf("A16 sizeof %d\n", sizeof(A16));
    printf("\n");
    return 0;
}
//AD.a 0
//AD.b 4
//AD.c 24
//AD sizeof 32
//
//A1.a 0
//A1.b 4
//A1.c 17
//A1 sizeof 25
//
//A2.a 0
//A2.b 4
//A2.c 18
//A2 sizeof 26
//
//A4.a 0
//A4.b 4
//A4.c 20
//A4 sizeof 28
//
//A8.a 0
//A8.b 4
//A8.c 24
//A8 sizeof 32
//
//A16.a 0
//A16.b 4
//A16.c 24
//A16 sizeof 32
//
//
zgl7903 2017-12-08
  • 打赏
  • 举报
回复
单独建一个工程, 把这个结构体拷贝过来 看看sizeof 是多少? 你项目中的sizeof 又是多少? 然后调整pack大小,对比下大小变化,
zgl7903 2017-12-07
  • 打赏
  • 举报
回复
#pragma pack(push, 8) //默认值 #include "kps_data.h" #pragma pack(pop)
monahans 2017-12-07
  • 打赏
  • 举报
回复
我建议你注意下操作系统和32位系统和64位系统区别。MAXLEN最好是64的倍数
monahans 2017-12-07
  • 打赏
  • 举报
回复
我也遇见了这个问题,在一个结构体重定义不同长度字符串后,然后把这个结构体内容写入文件时候在WIN10下有的机器上(XP,WIN7都正常)老是多出来一些东西。 我目前也没有想到好的对齐方法,我现在都直接把所有的字符串数组长度定义为64字节.好像就OK了。
smwhotjay 2017-12-07
  • 打赏
  • 举报
回复
对齐很坑的,有时数据都是一模一样,但是就是不一致,因为内存不对齐。 感觉问题不一定是内存对齐引起,
moonk-z 2017-12-07
  • 打赏
  • 举报
回复
引用 7 楼 shen_wei 的回复:
结构体最好的设计就是变量定义统一。。。。 否则对于数据的赋值就是memcpy来赋值。。。 对于定义字节对齐啥的,系统自有自己的处理方式,不同位数的系统也不相同!!
好吧- -实话说,这个func类不是我写的 是使用的代理类,通过工具自动生成的。在测试工程里没问题,添加到项目中就出现内存偏移的问题。陈年老项目真的坑多
shen_wei 2017-12-07
  • 打赏
  • 举报
回复
结构体最好的设计就是变量定义统一。。。。 否则对于数据的赋值就是memcpy来赋值。。。 对于定义字节对齐啥的,系统自有自己的处理方式,不同位数的系统也不相同!!
moonk-z 2017-12-07
  • 打赏
  • 举报
回复
引用 5 楼 shen_wei 的回复:
对于数据的话,可以使memcpy 函数。。。
我可以确定不是代码的问题,这个模块单独用一个工程单元测试过了,没问题才加进来的
shen_wei 2017-12-07
  • 打赏
  • 举报
回复
对于数据的话,可以使memcpy 函数。。。
moonk-z 2017-12-07
  • 打赏
  • 举报
回复
引用 3 楼 zgl7903 的回复:
MAXLEN 是否有多个定义? 是链接源码文件还是库? 编译器结构体对齐设置是否一致? 设置断点, 设置数据断点, 调试运行,监视内存指向的是否是同一地址?
MAX是宏定义,源码看得到,确定是只有一个数据--1024 编译器设置为默认,没敢动 这个监视内存指向的是否同一地址是监视哪两个的地址?
zgl7903 2017-12-07
  • 打赏
  • 举报
回复
MAXLEN 是否有多个定义? 是链接源码文件还是库? 编译器结构体对齐设置是否一致? 设置断点, 设置数据断点, 调试运行,监视内存指向的是否是同一地址?
moonk-z 2017-12-07
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903 的回复:
#pragma pack(push, 8) //默认值 #include "kps_data.h" #pragma pack(pop)
已经是这样写了,但是还会出现这个问题

16,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧