【请教】c++ 变量内存地址对齐的问题

NoneWithVoid 2010-09-02 05:37:49
代码如下:

struct st{
int id;
unsigned int num;
float price;
char str[15];
double total;
}


这是输出的各字段的内存地址:
0x22fef0 (id)
0x22fef4 (num)
0x22fef8 (price)
0x22fefc (str)
0x22ff10 (total)

st结构中的str占用15字节空间,内存按照4字节对齐=>total的地址为0x22fefc+16=0x22ff08,但输出的却是0x22ff10,多了4字节,这是怎么回事?

还有,内存对齐和系统相关,因此怎样才能根据st的首地址和偏移量求出total的地址呢?(这里不直接用.运算符,即不使用&st.total,如何按照st的地址求total的地址)

先谢谢了!
...全文
272 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
justkk 2010-09-03
  • 打赏
  • 举报
回复
整个结构的大小是里面占用字节最大的那个成员(对于数组,只考虑单个元素)的整数倍。
每个成员按照它占用的字节对齐,如int应该存放在4字节对齐的位置,double存放在8字节对齐的位置
成员之间不是紧密存储的,通常有缝隙
NoneWithVoid 2010-09-03
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 pengzhixi 的回复:]
引用 7 楼 freeyxm 的回复:
引用 1 楼 pengzhixi 的回复:
你先输出你的double的大小吧


你的意思是它是按照double对齐的,(我的机器double是8字节的)。
那为什么前面3个4字节的只占用4字节,而不是8字节呢?
那个str是15字节,占用了20字节的空间……
晕了~


最后double成员的起始地址应该被8整除,所以str要加5个字……
[/Quote]

谢谢,有点明白了。
昨天试了下,小于4字节的按4字节补齐,其它的按8字节补齐。

还不知道在其它机器上能行不……
NoneWithVoid 2010-09-03
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 justkk 的回复:]
为什么要定义struct st_map,它里面的信息你还得自己填充,有什么用处吗?
struct的各个成员之间不是紧密存放的,里面有填充字符..
[/Quote]

这个是为了实现与结构无关的一个算法,也就是不管给定的结构元素是多少,只要按照给定的模式进行设计就可以正常输出……
暂时没想到有啥好办法可以实现,看了些PE文件之类的寻址结构,就用它了……
pengzhixi 2010-09-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 freeyxm 的回复:]
引用 1 楼 pengzhixi 的回复:
你先输出你的double的大小吧


你的意思是它是按照double对齐的,(我的机器double是8字节的)。
那为什么前面3个4字节的只占用4字节,而不是8字节呢?
那个str是15字节,占用了20字节的空间……
晕了~
[/Quote]

最后double成员的起始地址应该被8整除,所以str要加5个字节才行。
xiehui3651 2010-09-03
  • 打赏
  • 举报
回复
最好的方法是自己手动对其,这样就不用怕了
justkk 2010-09-03
  • 打赏
  • 举报
回复
为什么要定义struct st_map,它里面的信息你还得自己填充,有什么用处吗?
struct的各个成员之间不是紧密存放的,里面有填充字符..
NoneWithVoid 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 justkk 的回复:]
估计在你的环境中double是8字节.
可以这样计算偏移量
(int) ((long) (&((struct st *)0)->total))
[/Quote]

用这个方法不错!

但我用的地方用不了,定义的结构模板如下:

stuct st_map{
int num;
unsigned int len1;
unsigned int addr1;
unsigned int len2;
unsigned int addr2;
//...
}



num存参数个数,以后每对存的是开始给出的id,price,total等的长度和地址,由于st的结构对于我来说是未知的,因此不能用任何与st有关系的方法,只能根据st的首地址,再根据st_map的信息一个一个的算……
这里就涉及到了无法确定char占用字节的问题……
NoneWithVoid 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 qf17331733 的回复:]
呵呵,string这个注意他后面会隐式的包含"/o"之类的结尾标记符,这些占据了4个字节~
[/Quote]

我用的是char,
NoneWithVoid 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 pengzhixi 的回复:]
按照double大小对齐
[/Quote]

用这个方法不错!

但我用的地方用不了,定义的结构模板如下:

stuct st_map{
int num;
unsigned int len1;
unsigned int addr1;
unsigned int len2;
unsigned int addr2;
//...
}

num存参数个数,以后每对存的是开始给出的id,price,total等的长度和地址,由于st的结构对于我来说是未知的,因此不能用任何与st有关系的方法,只能根据st的首地址,再根据st_map的信息一个一个的算……
这里就涉及到了无法确定char占用字节的问题……
qf17331733 2010-09-02
  • 打赏
  • 举报
回复
其实你可以把string str[15];改成 [16]之类的你就知道了,后面确实隐含"/o"之类的结束符~
NoneWithVoid 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 pengzhixi 的回复:]
你先输出你的double的大小吧
[/Quote]

你的意思是它是按照double对齐的,(我的机器double是8字节的)。
那为什么前面3个4字节的只占用4字节,而不是8字节呢?
那个str是15字节,占用了20字节的空间……
晕了~
qf17331733 2010-09-02
  • 打赏
  • 举报
回复
呵呵,string这个注意他后面会隐式的包含"/o"之类的结尾标记符,这些占据了4个字节~
yuyoucuobei 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yuyoucuobei 的回复:]

0x22ff10 - 0x22fefc
可不是4个字节,是24个字节
[/Quote]

额 算错了 是20个字节
yuyoucuobei 2010-09-02
  • 打赏
  • 举报
回复
0x22ff10 - 0x22fefc
可不是4个字节,是24个字节
justkk 2010-09-02
  • 打赏
  • 举报
回复
估计在你的环境中double是8字节.
可以这样计算偏移量
(int) ((long) (&((struct st *)0)->total))
pengzhixi 2010-09-02
  • 打赏
  • 举报
回复
按照double大小对齐
pengzhixi 2010-09-02
  • 打赏
  • 举报
回复
你先输出你的double的大小吧

64,676

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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