C中结构体的存储分配
对于C语言中结构体所占的存储空间的大小,也一直是笔试面试的常客,今天好好看了一下这方面,以前一直以为很清楚了,今天通过各种实际测试举例,发现原来还是没有搞透彻,好在现在是彻底懂了,所以和大家分享,希望能有所帮助。
提到结构体,相信大家都知道元素存储要对齐,话是没有错,只是这个“对齐”里面包含了很多微妙的东西。首先详细的给出结构体内存分配的原则吧:编译器按照成员列表顺序一个接一个地给每个成员分配内存。只有当存储成员时需要满足正确的边界对齐要求时,成员之间才可能出现用于填充的额外内存空间。接下来我们来慢慢理解这句话。
sizeof操作符能够得出一个结构的整体长度,包括因边界对齐而跳过的那些字节。所以一般都用sizeof来计算其所占存储空间。来看下面的例子:
struct test1
{
int a;
char b[];
char c;
};
计算可以得到test1占16个字节。原因是a占4个字节(32位机,int占4个字节),b和c分别占9个字节和1个字节,加起来10个字节,与a对齐,则需要12个字节,所以总共需要16个字节。这个例子就是我们最熟悉的,接下来看一下个。
struct test2
{
char b[];
int a;
char c;
};
计算可以得到test2占20个字节。比较test1和test2可以发现仅仅将a和b的位置换了一下,为什么结果会不同呢?这就是前面定义中所说的顺序的问题。int为最大字节,一开始分配9个字节,然后是a,为了对齐,这时候应该是12+4个字节,后面又来一个char,为了对齐加4,所以总共是20个字节。而test1因为后面两个类型一致,所以可以和在一起分配,然后对齐。
接下来我们在加大难度,看如下例子:
struct test3
{
char b[];
int a;
char c;
double d;
};
按照上面的逻辑,b占9个字节,a占4个字节,为了和a对齐,所以此时应该是12+,接着是c为1个字节总共为12++=,然后是d为8个字节,为了和8字节对齐,则应该为24+=32个字节,即最终结果为32个字节。变换一下顺序,得到如下例子:
struct test4
{
char b[];
int a;
double d;
char c;
};
同样的,b和a占据12+4个字节,d为8个字节,则应该是16+=,加上最后的一个字节,为了对齐,总共也是24+=32个字节。这里需要注意的是,若数组b元素改为13,则为了对齐,d前面应该是16+4,然后遇到d,对齐后为24+8,在加上最后的8个字节,应该为40个字节。
再来看一个:
struct test4
{
double d;
char b[];
int a;
char c;
};
d占8个字节,b占9个字节,后面是int,为了对齐,加上a应该是20+,再加上1个字节,为了和最大的double对齐,所以应该是20++=32个字节。
好了,通过列举这么多不同的例子,最终目标只有一个,是真的搞清楚某个结构体占据的空间大小。通过上面的例子,我总结了以下几点。
)首先,看该结构体中最大的“基元素”(这是我杜撰的,就是说基本元素类型最大的是哪个,例如test1和test2都是int,而test3和test4都是double,而不是看数组总共所占据的大小),找到这个以后,结构体所占据的空间的大小一定要是该基本元素所占空间大小的整数倍。
)接着,按顺序将元素进行排列。前一元素要与后一元素对齐,如果后一元素的“基元素”比前一个大,则前一元素需要调整大小,即对齐该后一元素。
)最后将得到的字节大小加起来,跟最大的基元素对齐,即得到最终的所占存储空间大小。
如果要确定结构中某个成员的实际位置,可以使用offsetof宏(stddef.h)offsetof(type,member)。type是结构的类型,member是该结构的成员名,表达式的结构是一个sizeof_t值。表示该指定成员的存数位置(离该结构体存储的起始位置)。
另外还有一点值得一提的是,当结构体里面包含另一结构体时,直接将该结构体中的内容代换进去,计算其总的存储空间即可。
http://blog.sina.com.cn/s/blog_67b077fe0101844k.html

C中结构体的存储分配的更多相关文章

  1. C#中结构体和类的区别

    结构体和类同样能够定义字段,方法和构造函数,都能实例化对象,这样看来结构体和类的功能好像是一样的了,但是他们在数据的存储上是不一样的 C#结构体和类的区别问题:这两种数据类型的本质区别主要是各自指向的 ...

  2. C语言中结构体对齐问题

    C语言中结构体对齐问题 收藏 关于C语言中的结构体对齐问题 1,比如: struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B; ...

  3. (一)一个工作任务引起的乱战——c#中结构体与byte[]间相互转换

    一个工作任务涉及到c#与c++系统间的udp通信,处理了蛮长时间没有完成任务,但是期间接触到不少小知识点.本人是初接触c#,c++语言没有接触过.可能写的东西都很小儿科,暂且记录下来当工作日记把. 先 ...

  4. 《挑战30天C++入门极限》C/C++中结构体(struct)知识点强化

        C/C++中结构体(struct)知识点强化 在上一个教程中我们已经简单的阐述了什么是结构体了,为了进一部的学习结构体这一重要的知识点,我们今天来学习一下链表结构. 结构体可以看做是一种自定义 ...

  5. C语言中结构体内存存储方式

    C语言中结构体内存存储方式 结构体的默认存储方式采用以最大字节元素字节数对其方式进行对齐,例如一个结构体中定义有char.int类型元素,则结构体存储空间按照int类型占用字节,如果还有double类 ...

  6. STM32L0系列EEPROM中结构体的读取

    在STM32L0中操作EEPROM本来参考了上篇操作FLASH的方法,多多少少都有些问题.我觉得可能是结构体在转换成其他变量的时候出了问题. 比如下面这段代码,在Windows上可以正常运行(使用g+ ...

  7. C语言中结构体赋值问题的讨论

    今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...

  8. OC中结构体作为对象属性

    在OC中结构体有时候也作为对象的属性 类的定义 #import <Foundation/Foundation.h> typedef struct{ int year; int month; ...

  9. C C++ 中结构体与类

    先来说说C和C++中结构体的不同 a) C语言中的结构体不能为空,否则会报错 1>d:\myproject\visual studio 2013\projects\myc++\main.c(71 ...

随机推荐

  1. PHP中的一些新特性

    PHP 5.6 1.可以使用表达式定义常量 https://php.net/manual/zh/migration56.new-features.php 在之前的 PHP 版本中,必须使用静态值来定义 ...

  2. Python监控文件变化:watchdog

    Python监控文件变化有两种库:pyinotify和watchdog.pyinotify依赖于Linux平台的inotify,后者则对不同平台的的事件都进行了封装.也就是说,watchdog跨平台. ...

  3. 使用 HTML5 History 新特性增强 Ajax 的体验(转)

    一. 场景再现 如大家熟知,Ajax 可以实现页面的无刷新操作,但会造成两个与普通页面操作(有刷新地改变页面)有着明显差别的问题—— URL 没有修改以及无法使用前进.后退按钮.例如常见的 Ajax ...

  4. 以宽字符形式读整个文件的内容(wifstream的使用)

    // TestShlwAPI.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h" #include <iostream>using s ...

  5. PowerDesigner列名作为注释

    Tools -> Execute Commands -> Edit/Run Script 执行以下脚本: Option Explicit ValidationMode = True Int ...

  6. Redis 实现队列优先级

    通常使用一个list来实现队列操作,这样有一个小限制,所以的任务统一都是先进先出,如果想优先处理某个任务就不太好处理了,这就需要让队列有优先级的概念,我们就可以优先处理高级别的任务. 实现方式: (1 ...

  7. mysql 5.6.23的源码安装

    http://634871.blog.51cto.com/624871/1325914 首先删除系统自带的mysql rpm -qa | grep mysql   rpm -e mysql   //普 ...

  8. PHP位操作符

    二进制怎么算 http://www.doc88.com/p-474114598610.html 这个涉及到系统底层,WEB开发中几乎没用到,知道下有这个东西就好了.底层的东西解释总是简单不了的. 变量 ...

  9. 【转】如何遍历json数据

    var value = { "china":{ "hangzhou":{"item":"1"}, "shang ...

  10. mini2440裸机音乐播放器(非常久曾经的笔记)

    [这是好久曾经写的.有点乱,没时间整理.当做记录用的.] 图片粘贴失效.没上传图,想要的直接下载文档吧. 项目目的:通过IIS,触摸屏,LCD模块实现音乐播放器功能(button上一首.下一首.播放. ...