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;
}
例如这篇文章:
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;
}
相关文章推荐
- C++继承和菱形继承中的虚继承
- c++ 的vector
- C/C++ 中的0长数组(柔性数组)
- 共用体union用法讲解
- #define指令的作用
- c++补做实验2
- 小端模式存储
- 模拟题 c/c++ 换酒喝问题
- c++——补第一次实验
- 理解c语言中的void*用法
- C++ Primer学习笔记(三) C++中函数是一种类型!!!
- 我所理解的C++反射机制
- 我所理解的C++反射机制
- c++补做实验1
- Windows下用C语言获取系统的CPU利用率、内存使用率、硬盘使用率等
- yolo.c中的函数定义
- C++泛型编程原理
- 4. Median of Two Sorted Arrays
- C++ 百炼成钢20
- Fopen 函数 C语言 (网上摘抄)(方便查询)