为动态分配结构体内存分配内存(请帮我看看问题在哪)

结构体的内存空间分配原理 - qintangtao - 博客园
关于内存对齐
1.什么是内存对齐
假设我们同时声明两个变量:
用&(取地址符号)观察变量a,
b的地址的话,我们会发现(以16位CPU为例):
如果a的地址是0x0000,那么b的地址将会是0x0002或者是0x0004。
那么就出现这样一个问题:0x0001这个地址没有被使用,那它干什么去了?答案就是它确实没被使用。因为CPU每次都是从以2字节(16位CPU)或是4字节(32位CPU)的整数倍的内存地址中读进数据的。如果变量b的地址是0x0001的话,那么CPU就需要先从0x0000中读取一个short,取它的高8位放入b的低8位,然后再从0x0002中读取下一个short,取它的低8位放入b的高8位中,这样的话,为了获得b的值,CPU需要进行了两次读操作。
但是如果b的地址为0x0002,
那么CPU只需一次读操作就可以获得b的值了。所以编译器为了优化代码,往往会根据变量的大小,将其指定到合适的位置,即称为内存对齐(对变量b做内存对齐,a、b之间的内存被浪费,a并未多占内存)。
2.结构体内存对齐规则
结构体所占用的内存与其成员在结构体中的声明顺序有关,其成员的内存对齐规则如下:
(1)每个成员分别按自己的对齐字节数和PPB(指定的对齐字节数,32位机默认为4)两个字节数最小的那个对齐,这样可以最小化长度。
(2)复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。
(3)结构体对齐后的长度必须是成员中最大的对齐参数(PPB)的整数倍,这样在处理数组时可以保证每一项都边界对齐。
(4)计算结构体的内存大小时,应该列出每个成员的偏移地址,则其长度=最后一个成员的偏移地址+最后一个成员数的长度+最后一个成员的调整参数(考虑PPB)。
下面举例说明上述规则:
#pragma pack(2) //指定PPB为2
char //偏移地址0
int //偏移地址2
char //偏移地址6
#pragma pack() //恢复原来默认PPB,32位下为4
int main(int argc,char * argv[])
printf("sizeof(struct T));
最后输出的结果为:8。语句#pragma pack(2)的作用是指定结构体按2字节对齐,即PPB=2。分析如下:
变量a默认为1字节,PB=2,所以a按1字节对齐,a的偏移地址为0。
变量b默认为4字节(在32位机器中int为4字节),PB=2,所以b按2字节对齐,b的偏移地址为2。
变量c默认为1字节,PB=2,所以c按1字节对齐,偏移地址为6。
此时结构体的计算出的字节数为7个字节。最后按规则3,结构体对齐后的字节数为8。sizeof(T)=6+1+1=8
(1)#pragma pack(2) //指定PPB为2
char //偏移地址0
char //偏移地址1
int //偏移地址2
则sizeof(T)=最后一个成员的偏移地址+最后一个成员数的长度=2+4=6。
struct T1{
char //偏移地址0
char //偏移地址1
int //偏移地址4
struct T2{
char //偏移地址0
int //偏移地址4
char //偏移地址8
PPB=4,则sizeof(T1)=4+4=8;sizeof(T2)=8+1=9,9不能整除4,故调整数为3,即sizeof(T2)=8+1+3=12
4.注意的问题
(1)字节对齐取决于编译器;
(2)一定要注意PPB大小,PPB大小由pragam pack(n)指定;
(3)结构体占用的字节数要能被PPB整除。
(1)sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用。
(2)终于搞懂struct结构体内存分配问题了,结构体中各个成员字节对齐遵循以下几个原则: 直接用下面几个原则即可判断结构体的大小
1.结构体每个成员相对于结构体首地址的偏移量(offset)都是(这个)成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internaladding);
例如有以下一个结构体
structex {
第1个成员偏移量为0,是int型成员大小4(假设这太机器的整型长度占4个字节)的整数倍。
第2个成员t为char型,他的大小为1,首先假设在成员i和t之间没有填充字节,由于i是整型,占4个字节那么在没有填充之前,第2个成员t相对于结构体的偏移量为4,他是t成员大小1的4倍,符合此条件,所以系统在给结构体第2个成员分配内存时,不会在i和t之间填充字节以到达对齐的目的。
当分配结构体第3个成员n时,首先发现是一个整型数据,大小为4,没有填充之前,n相对于结构体首地址偏移量为:前面2个成员+填充字节=5,所以当系统发现5不是4(成员大小)的整数倍时,会在成员t之后(或者说n之前)填充3个字节,以使n的偏移量到达8而成为4的整数倍。这样这个结构体占用内存情况暂时为4+1+3+4。
2.结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailingpadding)。
上面的结构体内存分配以后还要看是否满足此条件,假设在最末一个成员之后不需填充字节数,那么这个结构体的大小为12。而ex结构体中最宽基本类型成员为int,大小为4,12为4的整数倍,所以无须再在最末一个成员之后加上填充字节了。所以sizeof(ex)=12;
如果一个结构体如下所示
struc tex1{
那么sizeof(ex1)=16;原因就是在最后一个成员之后填充了3个字节。
3.还有一个额外的条件:结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
4.对于结构体成员属性中包含结构体变量的复合型结构体再确定最宽基本类型成员时,应当包括复合类型成员的子成员。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。
5总结出一个公式:结构体的大小等于最后一个成员的偏移量加上其大小再加上末尾的填充字节数目,即:
sizeof( struct ) = offsetof( last item ) + sizeof( last item ) +sizeof( trailing padding )为结构体分配内存(请帮我看看问题在哪)_百度知道
为结构体分配内存(请帮我看看问题在哪)
// 内存分配.cpp : 定义控制台应用程序的入口点。
#include &stdafx.h&
#include&stdio.h&
#include&stdlib.h&
struct student
int _tmain(int argc, _TCHAR* argv[])
struct student*
a = (struct ...
上边a[3]是忘记删的,对程序没影响还有就是和内存没关系,是结构体的问题。
我有更好的答案
a = (struct student*)malloc(sizeof(struct student)); 分配了一个大小 你循环赋值3次有问题读三次当然也有问题要想三次a = (struct student*)malloc(sizeof(struct student)*3);
采纳率:45%
来自团队:
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。如何用new来为结构体动态分配内存?_百度知道
如何用new来为结构体动态分配内存?
我有更好的答案
struct mystruct{}mystruct *pMySrt=pMySrt-&a=1;pMySrt-&b='a';cout&&pMySrt-&a&&&
&&&pMySrt-&b&&delete pMyS
采纳率:12%
为您推荐:
其他类似问题
您可能关注的内容
动态分配内存的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。在电子工程世界为您找到如下关于“结构体”的新闻
在STM32中经常遇到一些结构体的设置,结构体的好处不用多少了,仔细看《C语言设计》谭浩强版本,这样设计让项目很有层次,一目了然,这里介绍一下结构体指针在STM32库函数的应用,如下&例子: &&&(GPIO_TypeDef &*) &这里的作用是 把GPIO_BASE地址转换为GPIO_TypeDef结构体...
lpc11xx.h文件的寄存器定义是用结构体的形式,而reg51.h文件中,寄存器的定义都是一条一条的很直接的地址定义。然后是reg51.h文件中有sfr这样的“伪c语言”,而lpc11xx.h中用的是标准的c语言。C语言的最大用武之地就是单片机,要想学c,就在单片机上学,要想学单片机,就先入门c语言。两者相辅相成的学,效果最好。学以致用,才是学习的最终目标。2.lpc11xx.h...
;&&& //&浮点数
&EEP.F =&&&&&&& //
struct realti
& &nbsp...
#define&PERIPH_BASE&((u32)0x)//端口地址&?xml:namespace prefix = o ns = &urn:schemas-microsoft-com:office:office& /&
#define&APB2PERIPH_BASE&(PERIPH_B...
& & & & 在单片机开发中,经常会遇到要初始化一个外设,比如串口,它的初始化状态是由几个属性来决定的,比如串口号,波特率,极性及模式。对于这种情况,在我们没有学习结构体时,我们一般的方法是:
void USART_Init( u8 usartx , u32 BandRate , u8 parity , u8 mode...
偶然的一次发现,看到自己定义的结构体编译出来的大小和我想象的不一样,于是便追溯了一下根源。做了一系列实验之后发现,ARM的结构体的内存分配上有着一些固有的做法。废话不多说,看例子。
我定义一个结构体:
typedef struct TestStruct
&&& unsinged char Test1;
Arm结构体gcc内存边界对齐问题&
这段时间移植公司的linux i386程序到Arm linux平台,本以为是件工作量很小的事情,以为只要改几个驱动程序就OK了,没想到在应用程序这一块卡了很长时间。其中最烦的事情就莫过于结构体内存边界对齐了。搞了这么久,终于终结了一些小经验。&
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个...
既然既然相同长度单元格能放在一起,比如char1,char2,char3; int1,int2,int3; long1,long2,long3.在实际使用中,有些变量长度是不一样的,但由于它们之间相互关联也需要放在一起,那么要是不同长度的变量,想放在一起有没有办法呢?当然可以,这个就叫做结构体。现在按照数组的学习方法来研究结构体,两个问题,如何定义;如何访问结构体成员...
在LV和VC的WIN32 DLL之间传递下面结构体。
typedef struct& npm_axis
&&& int& axis_
&&& int &&&//初始速度
&&& int &nbsp...
最近看一段代码有所迷惑,先简单总结一下。有关结构体数组初始化的问题
struct &_m_usmart_nametab usmart_nametab[]=
#if USMART_USE_WRFUNS==1 //如果使能了读写操作
(void*)read_addr,&u32 read_addr(u32 addr)&,
结构体资料下载
指向结构体的指针 ARM_C语言程序...
结构体――通讯录.doc...
结构体定义,初始化,嵌套,应用等,适合初学者...
神龙卡中rm相关的结构体定义 神龙卡中rm相关的结构体定义...
关于结构体的一些知识看看吧!免费...
结构体的一些练习源代码,另外还有静态链表的使用...
C语言-桂林理工大学10-第十章 结构体.doc...
CC++与C#结构体和union对应表...
一个关于结构体数据的文件读写操作实例.linux/c...
这是在python里相对于c语言中的结构体的函数构建。class的用法...
结构体相关帖子
我看到很多开发板的IO口设置的程序中都有这样一条语句:GPIO_InitTypeDef GPIO_InitS& &这条语句什么意思,起什么作用。为什么GPIO_InitTypeDef和GPIO_InitStructure之间还加了一个空格,结构体是这样表示的嘛? 菜鸟的求助,希望可以得到解释! 前者一般是在.h文件中定义的结构体struct 名,后者是当前...
ST Open.Mems提供的osxMotionFX库实能够实现姿态数据输出对应的输出结构体osxMFX_output中的rotation_9X包含yaw(偏航), pitch(俯仰) and roll(横滚)三个数据在百度百科找到的解释是yaw(偏航):机体坐标系xb轴在水平面上投影与地面坐标系xg轴(在水平面上,指向目标为正)之间的夹角,由xg轴逆时针转至机体xb的投影线时,偏航角为正...
在C语言中,一个结构体的成员在个数确定数据类型不确定的情况下如何定义。这个typedef struct GetResp{
& & & & unsigned char GetRespT//*******响应类型
& &nbsp...
1描述:我遇到这样一个问题,在用MDK5进行stm32f4的程序调试过程中,我发现了如图所示的一个问题,观察发现,在结构体数组内部的成员变量(回调函数)的地址与定义函数的地址出现了偏差为1的情况,瞬间感觉特别熟悉,但是忘记在哪里学过了,呵呵,感觉很傻,请大家指点迷津!
GDISP_DRIVER_VMT是结构体数组,包括init回调函数这样的成员变量。_gmouseInitDriver...
------正在做STM32F429,用的是MDK,编译器总是用着不顺手。这不,又出了新问题了:
定义了一个结构体,在头文件中定义的,在C文件中引用,如果不加struct修饰,它将不认 ,只有加struct后才行。
而ST的例程中都是没有加struct的,为什么偏偏折磨我?
MDK为什么必须加上struct才行? 是你定义方式的问题吧,把代码贴出来看看
重新学c语言去,typedef党...
; && && && && && && && && && &&&/*定位ARP包地址*/
结构体后面的变量相加是怎样解释好呢?
结构体后面的变量相加是怎样解释好 指针操作,定位到帧的数据位...
数据打包的过程中,怎么把记录的一些标志位装到结构体里面呢& && && &&&紧急求助
结构体程序编写 bitfield,段位,如果你是要用到位变量的话,可以考虑这个方式。
但这个方式其实比较老了,现在属于lagacy语法,一般不用了。
除非你很缺空间,一般就不建议了。
或者另一种实现方式,用 位操作...
; && &&&:1;& && &
}stIsOutputA
这种结构体中的成员后面的:1是什么意思额。
STM32中关于结构体成员的赋值问题 位域,C语言...
大家看一下,我在头文件里定义的结构体,为什么编译的时候回报错呢?
请问我在头文件里定义的结构体为什么会报错? 问题根本不是在这个结构体,是你别的地方写错了,导致影响了这里。你可以把整个文件传上来。
你把工程发出来吧
像这样的情况 一般是没有在这个头文件里包含其他头文件的原因,导致找不到定义
附件已上传
[quote][size=2][url=forum.php?mod...
《嵌入式驱动工程师装逼指南》
搞嵌入式一定得搞驱动,简单的驱动咱还不做,至少也得是个块设备驱动,如果不是WiFi、网络设备,那根本都拿不出手。最好是个USB驱动,带OTG的,必须3.0,见个人喷头就问:你知道urb不?倍有面子!如果有人跟你谈platform虚拟总线,直接扭头就走,简直是拉低你的逼格,这年头,不懂device?tree,我都不跟他一块吃饭。写驱动,结构体一定行数越多越好,至少...
结构体视频
C程序设计视频教程(曾怡):本套视频教程由曾怡副教授讲解,使用教材为:《C程序设计》 谭浩强 清华大学出版社出版。是难得的C语言学习视频教程。全程共30讲,每讲45分钟左右。主要讲解了c语言概述、数据类型、运算符与表达式、顺序程序设计、选择机构程序设计、循环结构程序设计、数组、函数、指针、结构体...
《FreeRTOS源码详解与应用开发:基于STM32》辅以大量的例程,全面讲解了FreeRTOS的原理以及源码,主要内容包括任务管理和任务调度、系统裁减和配置、时间管理、队列、信号量、软件定时器、事件标志组、任务通知、低功耗Tickless模式、空闲任务以及内存管理等。同时,《FreeRTOS源码详...
《FreeRTOS源码详解与应用开发:基于STM32》辅以大量的例程,全面讲解了FreeRTOS的原理以及源码,主要内容包括任务管理和任务调度、系统裁减和配置、时间管理、队列、信号量、软件定时器、事件标志组、任务通知、低功耗Tickless模式、空闲任务以及内存管理等。同时,《FreeRTOS源码详...
你可能感兴趣的标签
热门资源推荐结构体数组到底要不要分配内存
clude&stdio.h&
struct student{char name[50];
}stu[2];/**************************************///结构体数组不需要分配内存,系统自动分配
/**************************************/typedef struct student STU;
STU creat(){for(i=0;i&2;i++){printf("pls input data:");scanf("%d",&stu[i].data); printf("pls input scroe:");scanf("%f",&stu[i].scrore);printf("pls input name:");getchar();scanf("%s",stu[i].name);
void display(){for(i=0;i&2;i++)
printf("%d ",stu[i].data);
printf("%f ",stu[i].scrore);
printf("%s ",stu[i].name);
printf("/n");
int main(void){creat();display(); getchar();getchar(); return 0;
经过程序可以看出结构体不会分配内存。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 动态分配结构体内存 的文章

 

随机推荐