当C程序运行在操作系统上时,操作系统会给每一个程序分配一定的栈空间。

堆为所有程序共有的,需要时需要申请访问。

一、栈

  局部变量、函数一般在栈空间中。  

  运行时自动分配&自动回收:栈是自动管理的,程序员不需要手工干预。方便简单。
  反复使用:栈内存在程序中其实就是那一块空间,程序反复使用这一块空间。
  脏内存:栈内存由于反复使用,每次使用后程序不会去清理,因此分配到时保留原来的值。
  临时性:(函数不能返回栈变量的指针,因为这个空间是临时的)
  栈会溢出:因为操作系统事先给定了栈的大小,如果在函数中无穷尽的分配栈内存总能用完。

二、堆  

  操作系统堆管理器管理:堆管理器是操作系统的一个模块,堆管理内存分配灵活,按需分配。
  大块内存:堆内存管理者总量很大的操作系统内存块,各进程可以按需申请使用,使用完释放。
  程序手动申请&释放:手工意思是需要写代码去申请malloc和释放free。
  脏内存:堆内存也是反复使用的,而且使用者用完释放前不会清除,因此也是脏的。
  临时性:堆内存只在malloc和free之间属于我这个进程,而可以访问。在malloc之前和free之后
  都不能再访问,否则会有不可预料的后果。

  

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. int main(void)
  4. {
  5. int *p=(int *)malloc(*sizeof(int));// a[1000]
  6. if(NULL==p)
  7. {
  8. printf("malloc error!\n");
  9. return -;
  10. }
  11. free(p);
  12. p=NULL;
  13. return ;
  14. }

三、段

  1.代码段

  存放代码的地方。只能访问,不能修改。

  代码段就是程序中的可执行部分,直观理解代码段就是函数堆叠组成的。

  2.数据段

  全局变量存放的地方。

  也被称为数据区、静态数据区、静态区):数据段就是程序中的数据,直观理解就是C语言程序中的全局变量。(注意:全局变量才算是程序的数据,局部变量不算程序的数据,只能算是函数的数据)

  3.bss段

  bss段的特点就是被初始化为0,bss段本质上也是属于数据段,bss段就是被初始化为0的数据段。

  注意区分:数据段(.data)和bss段的区别和联系:二者本来没有本质区别,都是用来存放C程序中的全局变量的。区别在于把显示初始化为非零的全局变量存在.data段中,而把显式初始化为0或者并未显式初始化(C语言规定未显式初始化的全局变量值默认为0)的全局变量存在bss段。

★有些特殊数据会被放到代码段  

  (1)C语言中使用char *p = "linux";定义字符串时,字符串"linux"实际被分配在代码段,也就是说这个"linux"字符串实际上是一个常量字符串而不是变量字符串。

    

  1. char *p="linux";//指针指向代码段“linux”
  2. char a[]="linux";//将代码段的“linux”复制到数据段或栈\堆中
  3.  
  4. *(p+)='c';//无法修改仍为"linux"
  5. a[]='c';//可以修改 为"lcnux"

  (2)const型常量:C语言中const关键字用来定义常量,常量就是不能被改变的量。const的实现方法至少有2种:第一种就是编译将const修饰的变量放在代码段去以实现不能修改(普遍见于各种单片机的编译器);第二种就是由编译器来检查以确保const型的常量不会被修改,实际上const型的常量还是和普通变量一样放在数据段的(gcc中就是这样实现的)。

★显式初始化为非零的全局变量和静态局部变量放在数据段
  (1)放在.data段的变量有2种:第一种是显式初始化为非零的全局变量。第二种是静态局部变量,也就是static修饰的局部变量。(普通局部变量分配在栈上,静态局部变量分配在.data段)

★未初始化或显式初始化为0的全局变量放在bss段
  (1)bss段和.data段并没有本质区别,几乎可以不用明确去区分这两种。

★总结:C语言中所有变量和常量所使用的内存无非以上三种情况。
  (1)相同点:三种获取内存的方法,都可以给程序提供可用内存,都可以用来定义变量给程序用。
  (2)不同点:栈内存对应C中的普通局部变量(别的变量还用不了栈,而且栈是自动的,由编译器和运行时环境共同来提供服务的,程序员无法手工控制);堆内存完全是独立于我们的程序存在和管理的,程序需要内存时可以去手工申请malloc,使用完成后必须尽快free释放。(堆内存对程序就好象公共图书馆对于人);数据段对于程序来说对应C程序中的全局变量和静态局部变量。
  (3)如果我需要一段内存来存储数据,我究竟应该把这个数据存储在哪里?(或者说我要定义一个变量,我究竟应该定义为局部变量还是全局变量还是用malloc来实现)。不同的存储方式有不同的特点,简单总结如下:
  * 函数内部临时使用,出了函数不会用到,就定义局部变量
  * 堆内存和数据段几乎拥有完全相同的属性,大部分时候是可以完全替换的。但是生命周期不一
  堆内存的生命周期是从malloc开始到free结束,而全局变量是从整个程序一开始执行就开始,
  直到整个程序结束才会消灭,伴随程序运行的一生。启示:如果你这个变量只是在程序的一个
  阶段有用,用完就不用了,就适合用堆内存;如果这个变量本身和程序是一生相伴的,那就
  适合用全局变量。(堆内存就好象租房、数据段就好象买房。堆内存就好象图书馆借书,数
  据段就好象自己书店买书)你以后会慢慢发现:买不如租,堆内存的使用比全局变量广泛。

C语言内存分配方法。的更多相关文章

  1. 关于c语言内存分配,malloc,free,和段错误,内存泄露

    1.   C语言的函数malloc和free (1) 函数malloc和free在头文件<stdlib.h>中的原型及参数        void * malloc(size_t size ...

  2. C语言内存分配

      (1)代码区(text segment).存放CPU执行的机器指令(machine instructions).通常,代码区是可共享的 (即另外的执行程序可以调用它),因为对于频繁被执行的程序,只 ...

  3. 内存分配方法 kmalloc()、vmalloc()、__get_free_pages()

    Copyright: 该文章版权由潘云登所有.可在非商业目的下任意传播和复制. 对于商业目的下对本文的任何行为需经作者同意. kmalloc #include <linux/slab.h> ...

  4. 【嵌入式开发】C语言 内存分配 地址 指针 数组 参数 实例解析

    . Android源码看的鸭梨大啊, 补一下C语言基础 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/detai ...

  5. 图解Go语言内存分配

    目录 基础概念 内存管理单元 内存管理组件 mcache mcentral mheap 内存分配流程 总结 参考资料 Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理. ...

  6. 内存管理 垃圾回收 C语言内存分配 垃圾回收3大算法 引用计数3个缺点

    小结: 1.垃圾回收的本质:找到并回收不再被使用的内存空间: 2.标记清除方式和复制收集方式的对比: 3.复制收集方式的局部性优点: https://en.wikipedia.org/wiki/C_( ...

  7. Go语言内存分配机制

    前言: 本文是学习<<go语言程序设计>> -- 清华大学出版社(王鹏 编著) 的2014年1月第一版 做的一些笔记 , 如有侵权, 请告知笔者, 将在24小时内删除, 转载请 ...

  8. C语言 内存分配 地址 指针 数组 参数 实例解析

    . Android源码看的鸭梨大啊, 补一下C语言基础 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/detai ...

  9. C语言内存分配函数malloc——————【Badboy】

    C语言中经常使用的内存分配函数有malloc.calloc和realloc等三个,当中.最经常使用的肯定是malloc,这里简单说一下这三者的差别和联系. 1.声明 这三个函数都在stdlib.h库文 ...

随机推荐

  1. 怎样在Redis通过StackExchange.Redis 存储集合类型List

    StackExchange 是由StackOverFlow出品, 是对Redis的.NET封装,被越来越多的.NET开发者使用在项目中. 绝大部分原先使用ServiceStack的开发者逐渐都转了过来 ...

  2. h1、h2、h3标签及strong标签对页面seo的影响

    今天和大家来聊下h1,h2,h3,strong几个标签,在网页中的使用对页面seo的影响,也阐述了个人的一些想法. 首先简要讲下H标签及strong标签的含义:<h1>.<h2> ...

  3. 第一篇 Entity Framework Plus 之 Audit

    一般系统会有登陆日志,操作日志,异常日志,已经满足大部分的需求了.但是有时候,还是需要Audit 审计日志,审计日志,主要针对数据增,改,删操作数据变化的记录,主要是对数据变化的一个追踪过程.其中主要 ...

  4. flask+sqlite3+echarts2+ajax数据可视化报错:UnicodeDecodeError: 'utf8' codec can't decode byte解决方法

    flask+sqlite3+echarts2+ajax数据可视化报错: UnicodeDecodeError: 'utf8' codec can't decode byte 解决方法: 将 py文件和 ...

  5. 充电时间 Go中的数组、切片、map简单示例

    数组是固定长度的,依稀让我想起了VB:切片是动态的:map一般是键值对 package main import ( "fmt" ) func main() { var userna ...

  6. 如何实现一个php框架系列文章【3】支持psr4的自动加载类

    psr4自动加载规范https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-4-autoloader-cn.md 我们把第三方使用psr规范的类库放在v ...

  7. linux添加启动器图标(Ubuntu为例)

     添加启动器图标,以eclipse为例,%表示命令提示符,shell命令:%nano /usr/share/applications/eclipse.desktop-----------[Deskto ...

  8. HttpClient调用webApi时注意的小问题

    HttpClient client = new HttpClient(); client.BaseAddress = new Uri(thisUrl); client.GetAsync("a ...

  9. sqlite索引的原理

    引言 这篇文章,里面讲到对于一个41G大小.包含百万条记录的数据库进行查询操作,如果利用了索引,可以把操作耗时从37s降到0.2s. 那么什么是索引呢?利用索引可以加快数据库查询操作的原理是什么呢? ...

  10. 移动信息化不能延续PC时代的痛

    当下,随着移动时代的到来,手机功能逐步完善,各个行业针对这一现象纷纷制定了相应的营销计划,于是霎时间兴起了一股网上订票/网上订饭/网上预约的热潮. 而对于IT行业,成为企业信息化最火的代名词莫过于移动 ...