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

百度了下,很多文章只是在告诉你一些内存对齐的理论,教你怎么算每个字段实际占用的内存。

 

例如这篇文章:

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;  
}  

 

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

下面这段代码可以在linux的源码中看到,用了“相减”:

struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
			   __SOCKADDR_COMMON_SIZE -
			   sizeof (in_port_t) -
			   sizeof (struct in_addr)];
  };

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值