| 网站首页 | 业界新闻 | 群组 | 交易 | 人才 | 下载频道 | 博客 | 代码贴 | 编程论坛
共有 398 人关注过本帖
标题:一道内存对齐问题产生的疑惑
只看楼主 加入收藏
S140131022
Rank: 2
来 自:重庆邮电大学
等 级:论坛游民
帖 子:201
专家分:30
注 册:2014-10-9
结帖率:90%
  已结贴   问题点数:20  回复次数:8   
一道内存对齐问题产生的疑惑
代码片段如下:
程序代码:
#include <stdio.h>
#pragma pack(4)
struct S1
{
    short a;
    long b;
};
struct S2
{
    char c;
    struct S1 d;
    double e;
};
#pragma pack()
int main()
{
    struct S2 s2;
    printf("%d\n", sizeof(struct S2));
    return 0;
}


我的理解是:
1、内存对齐有一个重要的规则就是,最终结构体的大小应该是各个成员的整数倍,但是此代码段结果却是20,很
显然它并不是double e(8字节)的整数倍,但是程序运行结果却实是20,请问是教材上那个内存对齐的规则错了,
还是我理解有误呢,谢谢大家!
2018-03-11 17:41
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:273
帖 子:5986
专家分:34173
注 册:2011-1-18
  得分:0 
没这话
但malloc返回的地址符合你说的规则
另外,你用的是vc私有功能,标准的应该用 http://zh.cppreference.com/w/cpp/language/alignas
2018-03-11 18:46
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:273
帖 子:5986
专家分:34173
注 册:2011-1-18
  得分:0 
贴错了 http://zh.cppreference.com/w/c/language/_Alignas
2018-03-11 18:47
S140131022
Rank: 2
来 自:重庆邮电大学
等 级:论坛游民
帖 子:201
专家分:30
注 册:2014-10-9
  得分:0 
回复 3楼 rjsp
感谢!

既然还有不甘心
就还没到放弃的时候~
2018-03-11 19:17
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:169
帖 子:6385
专家分:27937
注 册:2014-5-20
  得分:0 
这里与“自身对齐”和“指定对齐”有关
1、数据类型自身对齐最大的那个:double 8
2、指定对齐值:#pragma pack (4)
有效对齐值:自身对齐值和指定对齐值中小的那个 4
2018-03-12 06:00
S140131022
Rank: 2
来 自:重庆邮电大学
等 级:论坛游民
帖 子:201
专家分:30
注 册:2014-10-9
  得分:0 
回复 楼主 S140131022
今天又看到了一段c++程序,代码如下:
32位机器上定义了如下结构体:
[code]
struct xx
{
    long long x1;
    char _x2;
    int _x3;
    char _x4[2];
    static int _x5;
}
int xx::_x5;
[code]
sizeof(struct xx) = 24;
因为longlong 8 char 1 空3 int 4 char[] 2 等于18
又由于必须是各成员的整数倍,故取最小值为24;

请问为何这个代码需要取限定条件: 大小必须是成员的整数倍
而上面的代码却不必呢?

既然还有不甘心
就还没到放弃的时候~
2018-03-12 12:10
S140131022
Rank: 2
来 自:重庆邮电大学
等 级:论坛游民
帖 子:201
专家分:30
注 册:2014-10-9
  得分:0 
回复 5楼 吹水佬
大佬解答一下:
今天又看到了一段c++程序,代码如下:
32位机器上定义了如下结构体:
[code]
struct xx
{
    long long x1;
    char _x2;
    int _x3;
    char _x4[2];
    static int _x5;
}
int xx::_x5;
[code]
sizeof(struct xx) = 24;
因为longlong 8 char 1 空3 int 4 char[] 2 等于18
又由于必须是各成员的整数倍,故取最小值为24;

请问为何这个代码需要取限定条件: 大小必须是成员的整数倍
而上面的代码却不必呢?

既然还有不甘心
就还没到放弃的时候~
2018-03-12 12:11
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:4
帖 子:624
专家分:58
注 册:2005-8-5
  得分:0 
#pragma pack(4)

 表示 4 字节对齐,每个结构体成员的大小都要对齐到 4 字节。

你按照这个规则去算算看。
2018-03-12 12:29
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:169
帖 子:6385
专家分:27937
注 册:2014-5-20
  得分:20 
以下是引用S140131022在2018-3-12 12:11:30的发言:

大佬解答一下:
今天又看到了一段c++程序,代码如下:
32位机器上定义了如下结构体:

struct xx
{
    long long x1;
    char _x2;
    int _x3;
    char _x4[2];
    static int _x5;
}
int xx::_x5;

sizeof(struct xx) = 24;
因为longlong 8 char 1 空3 int 4 char[] 2 等于18
又由于必须是各成员的整数倍,故取最小值为24;

请问为何这个代码需要取限定条件: 大小必须是成员的整数倍
而上面的代码却不必呢?

这段没看到有“指定对齐”,只能从“自身对齐”看。
规则:结构体的自身对齐值是其成员中自身对齐值最大的那个值。这里最大的那个是 long long x1,其自身对齐值为8字节。所以,有效对齐值 8 字节:
第1块8字节:刚好存放 long long x1;
第2块8字节:可存放 char _x2; 和 int _x3; 同理_x2与_x3自身对齐值最大的,_x2加3字节补齐。
第3块8字节:可存放 char _x4[2]; 和 int _x5; 同理_x4与_x5自身对齐值最大的,_x4加2字节补齐。
总共分配24字节(3块8字节)存放各成员。
如果后面再增加一个成员:char _x6;
struct xx
{
    long long x1;
    char _x2;
    int _x3;
    char _x4[2];
    static int _x5;
    char _x6;
}
就要多增加一块:
第4块8字节:可存放 char _x6; _x6加7字节补齐。
总共分配32字节(4块8字节)存放各成员。




[此贴子已经被作者于2018-3-12 15:16编辑过]

2018-03-12 15:14







关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029306 second(s), 9 queries.
Copyright©2004-2018, BCCN.NET, All Rights Reserved