一、结构的存储分配

在座各位,肯定都明白机器内存分配对程序的运行效率有多重要。今天,首先我们就来梳一遍结构的存储分配问题。编译器按照成员列表的顺序,依次给每个成员分配空间。只有当存储成员时满足正确的边界对齐要求时,成员之间才可能出现用于填充的额外空间。系统禁止编译器在一个结构的起始位置跳过几个字节来满足边界对齐的要求,因此所有结构的存储位置必须是结构中边界要求最严格的数据类型所要求的位置。

如何优化内存的利用率呢?

在声明中对结构的成员进行排列,让那些对边界要求最严格的成员最先出现。我们知道这种做法可以人为大限度的减少因边界对齐而带来的空间损失。如何?现在就举一个例子:

struct example1{char   a;int    b;//假设该机器整形长度为4char   c;}

上例,每个结构占据十二个内存的字节空间,但实际只用6个。

struct example2{int    a;char   b;char   c;}

example2只占用八个字节的内存空间,节省了33%。但在实际工程操作中我们完全有理由为了可读性和可维护性将结构内部更相关的成员放在一起。当程序创建成百上千个结构时,减少浪费就显得尤为重要。如果我们必须确定某个成员的实际位置,应该考虑边界对齐因素,此时很难使用sizeof操作符。这种情况下可以使用offsetof宏(定义于stddef.h).

offsetof(  type  , member )

type 是结构类型,member是你需要的成员名。这个表达式返回一个值,表示这个指定成员开始存储的位置距离结构开始存储的位置偏移几个字节。例如对上面的example1声明而言:

offsetof( struct  example1  , b  )

返回的是4.

二、动态存储分配

c函数库提供两个函数,malloc和free,分别用于执行动态存储分配和释放。两个函数原型如下所示,它们都在头文件stdlib.h中声明。

void *malloc( size_t  size);
void  free( void  *pointer);

三、我们为什么使用动态内存分配

设想这样一个场景,一个旅馆有大量有限的客房,在旅游淡季的时候,暴露出我们第一个缺点:清洁阿姨要打扫大量的空房间,增大了酒店的维护成本。在旅游旺季的时候,旅馆爆满,此时暴露出我们第二个缺点,当大巴车运送来一车旅客的时候,我们痛苦的发现,没有足够的房间来安排此时一整辆车的旅客,要避免这种情况,我们可以把酒店建的足够大,但此时它的第一个缺点就加速恶化。解决这个方法逻辑很简单,只要在人们脑海中形成“客房永远不会满”这个概念,这就诱使他们不去选择建设有限容量的旅馆(典型例子见离散数学-布达佩斯大饭店)。我们可以将酒店的旅馆当作实际程序操作中的数组,建立一个永远不会溢出的数组非常诱人,即实现动态存储分配,那我们如何来完成这个永不溢出魔法呢?

现在我们解释原理,一个永远不会客满的旅店是什么样的?如何实现?我们通过借用的方法,维护一块居民地,当来客人的时候我们借用当地居民的空房间安排客人,客人离开的时候把房间的使用权还给居民,房间不停的借入和借出此时就很难产生没地方安排一车大巴旅客的问题。

同理,malloc和free函数一同维护一块内存池,当我们需要内存空间时,malloc函数就从系统内存为我们找到合适的空间并返回指针,当我们不需要此块内存时就可以用free函数释放将使用权交由系统。注意malloc函数是调用并返回指针的函数,如果这块内存的初始化非常重要,你要么自己动手对它进行初始化,要么使用calloc函数(下一板块描述)。

malloc函数的参数就是需要分配的字节数,假设我们需要得到分配一个结构需要的字节数,上面有一个offsetof函数,其返回值就是一个字节数(size_t)。malloc返回的类型是一个void * 的指针,一般要求你在转换时使用强制类型转换。如果操作系统无法向malloc提供一个合适的内存,它就返回一个null指针,所以在调用前确保函数返回的指针非空是一个非常重要的操作。 null空指针[^1]

free的参数要么是null,要么是之前从malloc、calloc或realloc返回的值。

[^1]:null空指针:NULL符号,定义与stdio.h,实际上的字面值为0.

四、calloc和realloc

calloc和realloc内存分配函数的原型如下:

void *calloc( size_t num_elements,size_t  element_size );
void *realloc( void *ptr , size_t  new_size );

calloc和malloc用法相同,都用于内存分配,但calloc在返回之前把它初始化为0.另一个不同是calloc在请求内存分配时,包括元素的数量,和每个元素的字节数,它计算总的内存分配。

realloc,顾名思义就是重新分配内存块的大小,它并不以任何方式初始化这块新内存。

五、使用动态分配内存

这里有一个例子,它用malloc分配一块内存:

int *pi;...pi=malloc( 100);if (pi==NULL){printf("out of memory!\n");exit(1);}

如果指针分配成功,我们将具有指向100个字节的指针。因为pi为一个整形指针,所以在整形值为4的机器上,将被当作具有25个整形元素的数组。我们还可以用以下方法声明:

pi=malloc(25* sizeof(int));

既然你有了这块指针,如何使用这块内存呢?如你所见,你既可以使用指针,也可以使用下标:

int *pi2,i;...pi2=pi;for( i=0;i<25;i++)*pi2++ =0;

或者:

int i;
...for( i=0;i<25;i+= 1)pi[i] =0;

以上,动态分配内容完成,还有一些常见错误整理和实例,我们在以后的实际运用中再来仔细讨论。

数据结构----内存分配问题相关推荐

  1. C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题?

    C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题? 问题1:结构体指针最开始怎么分配内存?用sizeof()是不能确定大小的. 问题2:给结构体变量分配之后,是否还要 ...

  2. 关于数据结构的内存分配问题

    博主开始用的是实验室的电脑VS2013,我也不知道是vs2013是没有还是我不会用,在surface上装了vs2015之后调试程序有内存监控[不过我现在发现直接可以在控制面板里找哈哈,就是在运行上一篇 ...

  3. redis 数据结构 内存管理 持久化

    为什么80%的码农都做不了架构师?>>>    Redis 内存数据结构与编码 OBJECT encoding key.DEBUG OBJECT key 简单动态字符串(simple ...

  4. lsd_slam 源码分析 数据结构 内存管理 Frame 图像金字塔 梯度金字塔 最大梯度值金字塔 逆深度值金字塔 逆深度方差值金字塔

    数据结构 lsd_slam代码 算法分析 Frame 帧类 详情 * 每张图像创建 5层的图像金字塔 每一层的尺度 变为上一层的1/2 * 图像的 内参数 也上上一层的 1/2 * 内参数求逆得到 内 ...

  5. C++成员函数的内存分配问题

    转自:http://blog.csdn.net/caomiao2006/article/details/4934013 1.所有函数代码都在程序编译连接时放在一块,称为代码区,无论是静态还是非静态函数 ...

  6. function module COM_PRODUCT_GETDETAIL_INTERNAL的内存分配问题

    Created by Jerry Wang, last modified on Jul 25, 2014 使用如下的report读取指定product的distribution chain信息: DA ...

  7. 图像转置时由于内存分配问题造成闪退的解决方案

    问题背景: 使用MFC框架(C++语言)进行图像处理,参考何斌<Visual C++ 数字图像处理(第二版)>中图像几何变换运算部分图像转置的代码. 问题描述: 在进行图像转置操作时,发现 ...

  8. 关于C语言中内存分配问题(malloc函数)

    malloc函数的原型: (void *)malloc(int size) malloc函数的返回值是一个void类型的指针,参数为int类型的数据,即申请分配的内存大小,单位是字节.内存分配成功之后 ...

  9. Android Dalvik虚拟机内存分配问题

    之前遇到一个android上图片加载不出来的问题,在三星的note3上极容易出现,而在nexus 4上则很难出现.后来通过DDMS观察发现,是某一个模块一直内存泄漏使得内存接近上限,导致一些大图(需要 ...

最新文章

  1. MySQL 常用运算符
  2. 量子运算 简单通俗例子_什么是量子计算机? 用一个简单的例子解释。
  3. Nginx设置TCP上游服务器的SSL配置
  4. php源码怎样安装mysql_Linux下源码包安装mysql、apache以及php
  5. 不知风险 何谈 5G?
  6. ASP.NET MVC动态二级域名及DNS(泛解析配置)
  7. 还不知道如何使用 IDEA ?教你三招快速掌握 IDEA
  8. 【自学C语言】自学C语言之与,或,异或关系
  9. 游戏背景音乐的种类—动态音效
  10. 计算机excel插入公式,Excel输入公式
  11. 个人博客如何申请ICP备案
  12. 桓公与轮扁:轮扁斫轮
  13. 去除VScode中的蓝色波浪线
  14. 用 Wwise 和 Unity 制作 DLC 使用 Wwise 文件包(File Package)
  15. 绝技不是一天练成 新手入库停车技巧图解
  16. sd卡受损格式化后还能恢复数据吗?
  17. 贝壳网webpack案例
  18. CSS系列之详解overflow
  19. 阿德莱德大学计算机科学学士排名,2020年阿德莱德大学计算机科学学士就业前景,入学要求介绍...
  20. 深聊全链路压测之:第二十一讲 | 如何搭建GoReplay压测平台。

热门文章

  1. 干货|深度学习实现零件的缺陷检测
  2. 状态码302.。。。
  3. RDKit | 基于RDKit和化学信息学探索化学空间
  4. 《机器学习Python实践》——数据导入(CSV)
  5. Linux(CentOS 7_x64位)系统下安装Xmgrace
  6. Java中Math类常用函数总结
  7. sangerbox平台使用(四)气泡图的绘制
  8. 微信小程序setinterval_微信小程序中setInterval的使用方法
  9. New Phytologist:王建军等综述全球变化下的山地微生物组和生态系统功能
  10. MPB:湖南农大尹杰组-猪粪便来源乳酸菌分离技术