您的位置:首页 > 编程语言 > C语言/C++

C++ 获取结构体内存对齐后的每个字段的大小

2016-06-17 12:19 387 查看
百度了下,很多文章只是在告诉你一些内存对齐的理论,教你怎么算每个字段实际占用的内存。

例如这篇文章:
http://wenku.baidu.com/link?url=n1FoivBissfKXjxVpXr36oPEGUfoImMEM1FFhpMdeMhnhg48fs5o0RxB6S2VTbErn9MDoy299TeAazp-hffxACK29sx2tmFS1ulr-TaMela
这是纯粹的为面试而讲解。而且面试中问内存对齐也确实总有人问。

理论我是懂一些的,但是我相信没几人能深信自己总是可以准确算出来每个字段的准确大小。即便你能算准,又能如何呢?

最重要的是:怎么让计算机获取结构体中每个字段的准确的占用内存大小呢?难道你要让我看了你的理论和算法后,手动算出来,写到程序里么!

怎么让计算机获取结构体中每个字段的准确的占用内存大小呢?

运行下面的代码吧,你就明白了。

你会发现,

直接用sizeof得到的内存大小是不准确的。

而准确的内存大小可以通过相减获得。

这在编程中是有实际意义的(很多时候,你会希望获取结构体中某个字段准确的长度)。

#define Enable

#ifdef Enable

struct st1

{
int i;
char c;
short s;

};

struct st2

{
char c;
int i;
short s;

};

void main()

{
st1 pst1;
st2 pst2;
unsigned int a1 = sizeof(pst1);
unsigned int a1_i = sizeof(pst1.i);
unsigned int a1_i_c = (unsigned int)(&pst1.c) - (unsigned int)(&pst1.i); // 下个字段的起始内存地址 - 当前字段的起始内存地址 = 当前字段实际占用的内存长度
unsigned int a1_c = sizeof(pst1.c);
unsigned int a1_c_c = (unsigned int)(&pst1.s) - (unsigned int)(&pst1.c); // 下个字段的起始内存地址 - 当前字段的起始内存地址 = 当前字段实际占用的内存长度
unsigned int a1_s = sizeof(pst1.s);
unsigned int a1_s_c = (unsigned int)(&pst1) + sizeof(pst1) - (unsigned int)(&pst1.s); // 结构体的截止内存地址 - 最后1个字段的起始内存地址 = 最后1个字段实际占用的内存长度

unsigned int a2 = sizeof(pst2);
unsigned int a2_c = sizeof(pst2.c);
unsigned int a2_c_c = (unsigned int)(&pst2.i) - (unsigned int)(&pst2.c); // 下个字段的起始内存地址 - 当前字段的起始内存地址 = 当前字段实际占用的内存长度
unsigned int a2_i = sizeof(pst2.i);
unsigned int a2_i_c = (unsigned int)(&pst2.s) - (unsigned int)(&pst2.i); // 下个字段的起始内存地址 - 当前字段的起始内存地址 = 当前字段实际占用的内存长度
unsigned int a2_s = sizeof(pst2.s);
unsigned int a2_s_c = (unsigned int)(&pst2) + sizeof(pst2) - (unsigned int)(&pst2.s); // 结构体的截止内存地址 - 最后1个字段的起始内存地址 = 最后1个字段实际占用的内存长度

}

#endif

另外,Intel、微软等公司曾经出过一道类似的面试题:

这个题目中也考察到了“相减”。

为何要考察呢?因为“相减”很有用,可以计算出准确的内存占用大小。

#include <iostream.h>  

#pragma pack(8)  

struct example1  

{  

    short a;  

    long b;  

};  

struct example2  

{  

    char c;  

    example1 struct1;  

    short e;      

};  

#pragma pack()  

int main(int argc, char* argv[])  

{  

    example2 struct2;  

    cout << sizeof(example1) << endl;  

    cout << sizeof(example2) << endl;  

    cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2) << endl;  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: