-
下面两个结构体的大小是多少?
2016-03-13 21:22:39struct studen1 { char str; short x; int num; }; struct student2 { char str; int num; short x; }; 答案:sizeof(strdent1) = 8; sizeof(student2) = 12;struct studen1{
char str;
short x;
int num;
};struct student2
{
char str;
int num;
short x;
};答案:sizeof(strdent1) = 8; sizeof(student2) = 12;
-
c++结构体内存大小
2017-03-25 22:14:05假如给你下面的结构体,让你计算该结构体的大小是多少,你会得出怎么样的答案:#include using namespace std;struct node1{ int a; char b; short c; }; struct node2{ char b; int a; short c; }; int main...假如给你下面的结构体,让你计算该结构体的大小是多少,你会得出怎么样的答案:
#include<iostream> using namespace std; struct node1{ int a; char b; short c; }; struct node2{ char b; int a; short c; }; int main(){ cout<<sizeof(node1)<<" "<<sizeof(node2); return 0; }
可能有的人会觉得node1和node2根本没有区别。这里我先给出答案,然后慢慢分析为什么是这样的。
是不是很奇怪,为什么是这个样子的。下面,我们一步一步来分析。在解决这个问题之前,我们需要知道什么叫做内存对齐。
在现代计算机体系中,每次读写内存中数据,都是按字(word,4个字节,对于X86架构,系统是32位,数据总线和地址总线的宽度都是32位,所以最大的寻址空间为232 = 4GB,按A[31,30…2,1,0]这样排列,但是请注意为了CPU每次读写 4个字节寻址,A[0]和A[1]两位是不参与寻址计算的。)为一个块(chunks)来操作(而对于X64则是8个字节为一个快)。注意,这里说的 CPU每次读取的规则,并不是变量在内存中地址对齐规则。既然是这样的,如果变量在内存中存储的时候也按照这样的对齐规则,就可以加快CPU读写内存的速 度,当然也就提高了整个程序的性能,并且性能提升是客观,虽然当今的CPU的处理数据速度(是指逻辑运算等,不包括取址)远比内存访问的速度快,程序的执 行速度的瓶颈往往不是CPU的处理速度不够,而是内存访问的延迟,虽然当今CPU中加入了高速缓存用来掩盖内存访问的延迟,但是如果高密集的内存访问,一 种延迟是无可避免的,内存地址对齐会给程序带来了很大的性能提升。
编译在编译的时候,会自动帮我们实现内存对齐,要想知道结构体的具体大小,我们就需要清除内存对齐的规则。
内存对齐的规则
一、起始位置为成员数据类型所占内存的整数倍,若不足则不足部分用数据将内存填充为该数据类型的整数倍。
二、 结构体所占总内存为其成员变量中所占空间最大数据 类型的整数倍
明白了规则,我们在来分析上面的结构体:假设结构体变量是从0号内存开始存储的,则有char型占1字节,int型4字节,short型2字节。然后,结合下图与内存对齐规则进行分析:
在node1中,5号空闲是因为不满足规则一。
在node2中,123空闲是因为不满足规则一,10、11空闲是因为不满足规则二。所以,我们就很容易得出node1的大小为8字节。node2为12字节。
-
如何判断一个结构体的大小
2015-08-23 10:59:02下面说一下如何判断一个结构体的大小。 首先需要了解总线宽度和自然边界这俩个概念,编译器在分配结构体时根据这俩个因素来计算偏移量和空间占用。 总线宽度: 总线宽度就是一个处理器访问周期最多可以访问多少位...对于嵌入式系统来说,内存很宝贵,那么在编程的时候就要尽量使自己用的数据结构所用的内存少,而结构体是C编程中经常用到的结构,保证结构体大小尽量的合理是很重要的。下面说一下如何判断一个结构体的大小。
首先需要了解总线宽度和自然边界这俩个概念,编译器在分配结构体时根据这俩个因素来计算偏移量和空间占用。
总线宽度:
总线宽度就是一个处理器访问周期最多可以访问多少位的数据。总线宽度分为BUS16,BUS32,BUS64。
自然边界:
每一个C的类型都有自然边界,如果某种类型数据所处地址是N的整数倍时访问效率最高,那么这种类型的自然边界就是数字N。
下面是C语言数据类型的大小和自然边界值:
对结构体而言,结构体的自然边界与最大的数据成员一致,也就是说结构体的大小就是元素的个数乘以最大成员的自然边界。其它元素中间需要填充字节。C数据类型
大小
BUS16
BUS32/64
Char
1
1
short
2
2
Int
4
2
4
指针
4
2
4
long
4
2
4
bit
---
很整形一样
float
4
2
4
double
8
2
4/8
struct
--
和具有最大需要的数据成员一致
union
--
和具有组大的数据成员一致
下面是几个例子,都是对于BUS32说的,BUS16和64都对照表就行了:
注意自然边界不都是等于该数据类型的大小。struct simple { char a;`//它的自然边界就是int的自然边界,所以它的大小为12. int b; //它的结构是这样的:{a000bbbbc000},每一个字母代表一个字节,0代表填充字节 char c; }; struct outer { char x;<span style="white-space:pre"> </span><span style="font-family: Arial, Helvetica, sans-serif;">//simple的自然边界是4,所以char也要填充数据,大小为16</span> struct simple y; //{x000{a000bbbbc000}} }; struct point<span style="white-space:pre"> </span>//自然边界是double,4,大小为20,{c000xxxxxxxxyyyyyyyy} { char c; double x,y; };
写个小程序测试一下对不对。#include <stdio.h> struct simple { char a; int b; char c; }; struct outer { char x; struct simple y; }; struct point { char c; double x,y; }; int main() { struct simple vect[2]; //printf("%d\n",sizeof(struct simple)); //printf("%d\n",sizeof(vect)); //printf("%d\n",sizeof(struct outer)); printf("%d\n",sizeof(struct point)); return 0; }
-
linux下结构体大小的计算
2018-04-04 15:58:30结构体的sizeof到底多大? struct node{ int a; int b;};问:sizeof(Node)是多少? 答案很简单,在32位机器上,一个int是4个字节,两个int就是8个字节,sizeof(Node)就是8。好的,上面那个答案确实是8,那么再看...
struct node{int a;
int b;
};问:sizeof(Node)是多少? 答案很简单,在32位机器上,一个int是4个字节,两个int就是8个字节,sizeof(Node)就是8。
好的,上面那个答案确实是8,那么再看下面这个结构体:
struct node{
char a;
int b;
};问:这个时候sizeof(Node)又是多少呢? int是4个字节,char是1个字节,答案是5?
这回,没有那么幸运,经过在机器上的操作,答案是8! Why?
实际上,这不是语言的问题,你在ANSI C中找不到为什么会这样!甚至你在不同的体系结构、不同的编译器下会得到不同的答案。那么,到底是谁把5改成了8呢?
这就引入了一个概念,叫做“内存对齐”。所谓的内存对齐,是指一种计算机体系结构(如X86)对基本数据类型的存储位置有限制,要求其地址为某个数的倍数,通常这个数为4或8。这种要求会简化处理器的设计以及提升数据访问的效率。至于为什么会有这样的设计,简单的说访存总线的位数固定,以32位总线为例,地址总线的地址总是4对齐的,所以数据也四对齐的话,一个周期内就可以把数据读出。这里不理解的话可以跳过去,只要记得对齐这回事儿就行了。如果想更深入的理解,可以看这里另一篇文章。
知道这个之后,那么我们就可以理解,实际上是编译器为了效率,在相邻的变量之间放置了一些填充字节来保证数据的对齐。X86结构是4对齐的,所以sizeof(Node)是8不是5。
再来看一个例子:
struct node{
int a;
char b;
char c;
int d;
char e;
};这时的sizeof(Node)是多少呢?没错,是16。
好的,既然我们知道对齐是由编译器来作的,那么我们可不可以更改对齐数呢? 答案是可以的,在C语言中,我们可以通过
#pragma pack(n)
来更改对齐模数。
注:以上都是在现x86 linux下使用gcc编译器验证,不乏有其他系统和编译器会得到不同的结果。
再让我们来看个例子:
struct node {
double a;
int b;
int c;
char d;
};这个时候的sizeof(node)是多少?20?24?
其实,这个时候你会发现,当你在windows上使用VC编译的时候,你会得到24;当你在linux上使用gcc编译的时候,你会得到20!其实,这恰好说明这种数据的对齐是由编译器决定的!在VC中规定, 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;而在gcc中规定对齐模数最大只能是4,也就是说,即使结构体中有double类型,对齐模数还是4,所以数据是按照1,2,4对齐的。所以,在两个不同编译器上,你得到了不同的答案!
-
结构体的内存对齐
2018-08-02 00:12:08首先,先来算一下,下面的这个例子,这些结构体的大小是多少呢? struct s4 { char c1; struct s3 a; double b; }; struct s3 { double b; char c; int i; }s3,*p; struct s2 { char c1; char c2; int ... -
VS2017设置结构体字节对齐大小
2020-08-18 14:36:14是因为结构体存在字节对齐的概念,为了提高存取效率,32位的计算机,一次可以读取4个字节的内存,如果不进行字节对齐操作,读取一个 int 值的数据,可能需要两次读取内存操作,大大的减小了内存读取效率,这个编译器... -
结构体中的内存对齐操作
2015-07-21 10:06:35再说这个之前,先看看下面一个结构体的大小是多少: struct data{ char a; int b; char c; } 答案是12!按照一般逻辑思路各个成员的大小加起来不就是了么? 但是实际的情况并不是这样的,结构体在实际的内存分配中... -
结构体对齐
2016-12-16 10:21:26结构体对齐 ...为了避免混淆,做如下规定,以下代码若不加特殊说明都运行于32位平台,结构体的默认对齐值是8,各数据类型所占字节...请问下面的结构体大小是多少? struct Test { char c ; int i ; }; 这 -
C语言结构体内存对齐
2020-03-22 18:10:51结构体所占的内存大小是其成员所占内存之和,但如果我们定义了一个空的结构体,那么它的大小是多少?考虑下面的这种情况: typedef struct empty_struct_s { }empty_struct_t; 经过测试,在gcc上,使用siz... -
C/C++结构体四字节数据对齐
2018-04-09 13:12:33为了避免混淆,做如下规定,以下代码若不加特殊说明都运行于32位平台,结构体的默认...两个例子请问下面的结构体大小是多少?struct Test { char c ; int i ; };这个呢?struct Test1 { int i ; double d ; cha... -
C/C++ 结构体 字节对齐原则详细举例解释 及sizeof的基本用法
2012-10-17 10:10:39VC中下面几个结构体大小分别是多少呢 struct MyStruct { double m4; char m1; int m3; }; struct MyStruct { char m1; double m4; int m3; }; #pragma pack(push)//保存对齐状态 ... -
C/C++中结构体字节对齐原理
2020-06-02 21:47:55首先看下面定义的结构体所占空间内存的大小是多少呢? #include <iostream> using namespace std; struct student // 定义结构体 { char a; // 1个字节 int b; // 4个字节 }stu; int main() { cout... -
C语言深度剖析--结构体
2012-07-12 09:30:35结构体所占的内存大小是其成员所占内存之和(关于结构体的内存对齐,请参考预处 理那章)。这点很容易理解,但是下面的这种情况呢? struct student { }stu; sizeof(stu)的值是... -
内存对齐的问题
2010-02-09 17:50:00内存对齐问题是每一个c程序员都应该考虑过的问题,c... } 在32位x86机器上它的大小是多少呢?是12,为什么呢?因为该结构体中最长的类型是int,因此需要按照4字节对齐,因此a和c后面都要pad进去3个无辜的字节,是不 -
非内建数据类型的编译器对其规则
2016-04-23 10:57:56非内建数据:用户自己定义的数据类型 比如,结构体,联合体,类 C/C++数据对齐 ...为了避免混淆,做如下规定,以下代码若不加特殊说明都运行于32位平台...请问下面的结构体大小是多少? struct Test { char c ; -
C/C++数据对齐(解决笔试中sizeof的问题)
2011-10-24 20:14:42C/C++数据对齐 ...为了避免混淆,做如下规定,以下代码若不加特殊说明都运行于32位平台,结构体的默认对齐值是8,各数据类型所占字节数...请问下面的结构体大小是多少? struct Test { char c ; int i ; }; -
VC++中关于字节对齐的问题
2015-03-22 10:38:00VC中下面几个结构体大小分别是多少呢? 1 struct MyStruct 2 { 3 double m4; 4 char m1; 5 int m3; 6 }; 7 8 struct MyStruct { 9 char m1; 10 double m4; 11 int m3; 12 }; 13 ... -
空类的背后
2012-02-23 10:36:33记得有次电话面试,面试官问我一个空类的大小是多少,当时自己回答是0字节,但后来验证了一下才知道原来是1字节。为什么空类的大小是1字节呢,而不是4字节或其它呢? 从下面的代码结合来分析一下: #include ... -
C中struct的对齐分析
2010-05-10 22:10:00转自http://hi.baidu.com/sunkanghome/blog/item/3d0804af55fa4bc57cd92a14.html参考http://hi.baidu.com/lbxthinker/blog/item/b116d9a3ad6cffa4caefd020.htmlVC中下面几个结构体大小分别是多少呢struct MyStruct {... -
大话C++之:内存对齐
2020-08-05 20:59:29问题是:这个结构体大小是多少? 很多人回答可能是5个字节。分析结构体的组成是:char占1个字,int占4个字节。1+4=5,没错吧? 其实这个答案应该是:不确定。因为它给的条件不能够得出一个确定的答案。 打开VS 2017... -
C/C++数据对齐!知识点来啦!小本本拿出来!
2019-09-26 14:46:51为了避免混淆,做如下规定,以下代码若不加特殊说明都运行于32位平台,结构体的默认对齐...请问下面的结构体大小是多少? structTest { charc ; inti ; }; 这个呢? structTest1 { inti ; doubled ; cha...