C语言跟内存分配方式

(1)

从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。

(2)

在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多

C语言跟内存申请相关的函数主要有alloca、calloc、malloc、free、realloc、sbrk等。

其中alloca是向栈申请内存,因此无需释放.

malloc分配的内存是位于堆中的,并且没有初始化内存的内容,因此基本上malloc之后,调用函数memset来初始化这部分的内存空间.

calloc则将初始化这部分的内存,设置为0.

而realloc则对malloc申请的内存进行大小的调整.申请的内存最终需要通过函数free来释放.

而sbrk则是增加数据段的大小;

malloc/calloc/free基本上都是C函数库实现的,跟OS无关.C函数库内部通过一定的结构来保存当前有多少可用内存.如果程序malloc的大小超出了库里所留存的空间,那么将首先调用brk系统调用来增加可用空间,然后再分配空间.free时,释放的内存并不立即返回给os,而是保留在内部结构中.

可以打个比方:

brk类似于批发,一次性的向OS申请大的内存,而malloc等函数则类似于零售,满足程序运行时的要求.这套机制类似于缓冲.

使用这套机制的原因:

系统调用不能支持任意大小的内存分配(有的系统调用只支持固定大小以及其倍数的内存申请,这样的话,对于小内存的分配会造成浪费;

系统调用申请内存代价昂贵,涉及到用户态和核心态的转换.

函数malloc()和calloc()都可以用来分配动态内存空间,但两者稍有区别。

malloc()函数有一个参数,即要分配的内存空间的大小:

Void

*malloc(size_t size);

calloc()函数有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的内存空间的大小:

void*calloc(size_t

numElements,size_t sizeOfElement);

如果调用成功,函数malloc()和calloc()都将返回所分配的内存空间的首地址。

malloc()

函数和calloc()函数的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由malloc()函数分配的内存空间原来没有被使用过,则其中

的每一位可能都是0;反之,如果这部分内存空间曾经被分配、释放和重新分配,则其中可能遗留各种各样的数据。也就是说,使用malloc()函数的程序开

始时(内存空间还没有被重新分配)能正常运行,但经过一段时间后(内存空间已被重新分配)可能会出现问题。

calloc()

函数会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那么这些元素将保证会被初始化为零;如果你是

为指针类型的元素分配内存,那么这些元素通常(但无法保证)会被初始化为空指针;如果你是为实数类型的元素分配内存,那么这些元素可能(只在某些计算机

中)会被初始化为浮点型的零。

malloc()

函数和calloc()函数的另一点区别是calloc()函数会返回一个由某种对象组成的数组,但malloc()函数只返回一个对象。为了明确是为一

个数组分配内存空间,有些程序员会选用calloc()函数。但是,除了是否初始化所分配的内存空间这一点之外,绝大多数程序员认

为以下两种函数调用方式没有区别:

calloc(numElements

,sizeOfElement);

malloc(numElements

*sizeOfElement) ;

需要解释的一点是,理论上(按照ANSIC标准)指针的算术运算只能在一个指定的数组中进行,但是在实践中,即使C编译程序或翻译器遵循这种规定,许多C

程序还是冲破了这种限制。因此,尽管malloc()函数并不能返回一个数组,它所分配的内存空间仍然能供一个数组使用(对realloc()函数来说同

样如此,尽管它也不能返回一个数组)。

总之,当你在calloc()函数和malloc()函数之间作选择时,你只需考虑是否要初始化所分配的内存空间,而不用考虑函数是否能返回一个数组。

当程序运行过程中malloc了,但是没有free的话,会造成内存泄漏.一部分的内存没有被使用,但是由于没有free,因此系统认为这部分内存还在使用,造成不断的向系统申请内存,是的系统可用内存不断减少.但是,内存泄漏仅仅指程序在运行时,程序退出时,OS将回收所有的资源.因此,适当的重起一下程序,有时候还是有点作用。

malloca/alloca:

内存分配函数,与malloc,calloc,realloc类似。但是注意一个重要的区别,_alloca是在栈(stack)上申请空间,用完马上就释放。

alloca包含在头文件malloc.h中,在某些系统中会宏定义成_alloca使用。

注意:

1)在调用

alloca的函数返回的时候, 它分配的内存会自动释放。也就是说, 用

alloca

分配的内存在栈上。所以释放不需要用户使用free。

2)alloca不具可移植性,而且在没有传统堆栈的机器上很难实现。当它的返回值直接传入另一个函数时会带来问题,因为他分配在栈上.

总结:由于这些原因,alloca不宜使用在必须广泛移植的程序中,

不管它可能多么有用。

realloc:

重新分配内存并返回void类型,如果没有足够的内存扩展内存块,则原来的指向的内存指针无变化,并返回NULL;如果重新分配大小设为0,而释放原来的内存块,

并返回NULL。

new:

分配内存的对象或数组类型的对象和返回一个适当类型,并调用对象的构造函数及在delete时调用对象的析构函数。其实现基于malloc调用。

下面是windows系统提供的API函数:

1、VirtualAlloc/VirtualAllocEx

在虚拟地址空间中保留或提交内存,

每次操作大小为Page页大小(windows一般为4K)的整数倍,因此需要自己计算内存分配算法(可以使用HeapAlloc或GlobalAlloc由系统自动分配计算),在没有使用MEM_RESET的情况下会初始化内存块(0),

VirtualAllocEx还可以在其他进程中的保留内存操作,并使用其对应的VirtualFree/VirtualFreeEx释放内存

2、HeapAlloc/HeapFree

在指定的Heap中分配内存,heap应该由CreateHeap或GetProcessHeap返回,分配的内存不能移动,CreateHeap创建的堆只能在调用的进程中使用,因此如需跨进程调用不能使用此种分配方式,由HeapFree释放.

3、GlobalAlloc/GlobalFree

从全局堆分配指定字节的内存,分配的内存可跨进程访问,并使用8字节对齐方式,

由GlobalFree释放,在使用GlobalAlloc分配的内存块时需调用GlobalLock和GlobalUnlock函数。

PS:为了更好的理解内存分配,我们可以了解一下内存分区。

1)栈区(stack)—

由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2)堆区(heap)

— 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 。

3)全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。

-程序结束后有系统释放。注意:全局区又可分为未初始化全局区:.bss段和初始化全局区:data段。

4)常量区—常量字符串就是放在这里的。程序结束后由系统释放

5)代码区—存放函数体的二进制代码。

c语言中alloc作用,C语言内存分配 :malloc()函数与alloc()函数相关推荐

  1. c语言中fflushstdin作用,C语言fflush(stdin)函数是什么意思,在什么情况下用它

    C语言fflush(stdin)函数是什么意思,在什么情况下用它 來源:互聯網  2009-04-22 18:49:31  評論 分類: 電腦/網絡 >> 程序設計 >> 其他 ...

  2. c语言中short作用,C语言short

    C语言short教程 C语言short定义详解 语法 short int varname = value; short varname1 = value2; //简写形式 参数 参数 描述 short ...

  3. const在c语言中作用,在C语言中const作用全面总结.doc

    在C语言中const作用全面总结 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助.Const 是C++中常 ...

  4. const 作用 c语言,在C语言中const 作用的的全面总结.doc

    右面拒账则川盾衡徊洁豁却尤骂登硫矢窍松寝春摘慌瘪悯嚏蓑篓雍淫东佳粮瘤遍榜柔脾右晕沮椒肃蛾闲惹戚谩智胜汁秀玉怠继纺侥圃唯需齿翟顿稽吩餐音欧宪撅虐镁级脖铲贵酋挚昂藕瓢需冷乃依萎听滚俄郭奴痈急欲沾挂畅好姐载 ...

  5. c语言中short作用,C语言中short的意思

    short和int等一样,是C或C++的一种内部数据类型.用于表示有符号整数. 不同的是,他们在内存中所占的空间大小不同,short通常为int所占一半,也有一些实现为和int一样,但不会比int大. ...

  6. 在c语言中char型数据在内存中的储存形式为什么

    在c语言中char型数据在内存中的储存形式为"ASCII码".在C语言中,将一个字符常量放到一个字符变量中,实际并不是把该字符本身放到内存单元中,而是将与该字符相对应的ASCII码 ...

  7. 在c语言中 char型数据在内存中的存储形式是,在c语言中char型数据在内存中的存储形式是什么?...

    在c语言中char型数据在内存中的存储形式是ASCII码.在C语言中,char型数据是将一个字符常量放到一个字符变量中,并不是把该字符本身放到内存单元中去,而是将该字符的相应的ASCII代码放到存储单 ...

  8. 转载——C语言中float,double类型,在内存中的结构(存储方式)

    最近在做一个数据格式分析和转换的项目,第一次接触底层的二进制代码存储,看的一头雾水,看到这个帖子后对于在Windows系统下数据的存储方式有了更多的了解,将原文分享一下: 原文地址为http://ww ...

  9. 【嵌入式C语言】内存分配 malloc 和 free

    文章目录 永不分离的 malloc 和 free 1. 简介 2. void * 3. malloc 4. free 5. malloc.free 小结 5.1.连续内存块 5.2.双宿双飞才好 5. ...

最新文章

  1. docker部署openvas
  2. 认真了解一下javascript
  3. ES6之字符串扩展方法(常用)
  4. SQL Server 2012入门T-SQL基础篇:(2)SQL的两个基础概念
  5. 福州PHP讲师招聘_“艺”起就业|招聘信息汇总
  6. 安卓WindowManager注入事件如何跳出进程间安全限制
  7. 近来很多人通过这个博文加关注,为何?
  8. 蚂蚁金服CTO程立:创新发展数字时代金融关键技术
  9. 无限分类左右值实现算法
  10. 编写一个简单Java程序,计算银行年存款的本息
  11. 手把手带你使用ZigBee——通过爱智控制EFR32,以及 Simplicity Studio 使用过程中注意事项
  12. 【C++学习笔记2】构造函数、析构函数、函数多态、抽象类、函数模板
  13. 中国将在 Sailfish 基础上开发移动操作系统
  14. mysql建表语句enum_mysql创建表语句格式
  15. 致敬Gif之父,使用Java生成Gif图片
  16. 哪个牌子的电视盒子好用?罗鹏数码盘点2023电视盒子排名
  17. AC米兰 传统豪门的没落
  18. 大恒水星相机开发记录
  19. android使用webview登录,android – 使用WebView登录Twitter
  20. 导航面板[ExtJS4]ExtJS4左边菜单面板收缩展开,右边TabPanel内容动态更新(解决宽度不能自适应问题)

热门文章

  1. 成功解决[libopenh264 @ 000001dc01594420] Incorrect library version loaded
  2. 征服c指针_征服C指针(C程序员必读经典 原版畅销11年)
  3. 图形学应用_着色器实例—笔刷效果
  4. invalid index of a 0-dim tensor. Use `tensor.item()`
  5. 综合练习之--1、复用布局页面显示XLV 和 侧滑 vp效果
  6. ps 设计神器,一键生成配色方案!
  7. ai课工场java标识,课工场《AI入门技巧制作抽象图案》
  8. 我们常用的软件就是这样耍流氓的
  9. 如何优化 Mac 笔记本电脑的电池续航能力,解决电池问题
  10. 苹果首台“双卡手机”,为什么只特供给部分地区?