我们知道,内存分为动态内存和静态内存,我们先讲静态内存。

一、静态内存

内存管理---存储模型

存储模型决定了一个变量的内存分配方式和访问特性,在C语言中主要有三个维度来决定:1、存储时期 2、作用域 3、链接

1、存储时期

存储时期:变量在内存中的保留时间(生命周期)

存储时期分为两种情况,关键是看变量在程序执行过程中会不会被系统自动回收掉。

1) 静态存储时期 Static

在程序执行过程中一旦分配就不会被自动回收。

通常来说,任何不在函数级别代码块内定义的变量。

无论是否在代码块内,只要采用static关键字修饰的变量。

2) 自动存储时期 Automatic

除了静态存储以外的变量都是自动存储时期的,或者说只要是在代码块内定义的非static的变量,系统会肚脐自动非配和释放内存;

2、作用域

作用域:一个变量在定义该变量的自身文件中的可见性(访问或者引用)

在C语言中,一共有3中作用域:

1) 代码块作用域

在代码块中定义的变量都具有该代码的作用域。从这个变量定义地方开始,到这个代码块结束,该变量是可见的;

2) 函数原型作用域

出现在函数原型中的变量,都具有函数原型作用域,函数原型作用域从变量定义处一直到原型声明的末尾。

3) 文件作用域

一个在所有函数之外定义的变量具有文件作用域,具有文件作用域的变量从它的定义处到包含该定义的文件结尾处都是可见的;

3、链接

链接:一个变量在组成程序的所有文件中的可见性(访问或者引用);

C语言中一共有三种不同的链接:

1) 外部链接

如果一个变量在组成一个程序的所有文件中的任何位置都可以被访问,则称该变量支持外部链接;

2) 内部链接

如果一个变量只可以在定义其自身的文件中的任何位置被访问,则称该变量支持内部链接。

3) 空链接

如果一个变量只是被定义其自身的当前代码块所私有,不能被程序的其他部分所访问,则成该变量支持空链接 我们来看一个代码示例:

[cpp] view plain copy

1. #include

2.

3. int a = 0;// 全局初始化区

4. char *p1; //全局未初始化区

5.

6. int main()

7. {

8. int b; //b在栈区

9. char s[] = "abc"; //栈

10. char *p2; //p2在栈区

11.

12. char *p3 = "123456"; //123456\0在常量区,p3在栈上。

13. static int c =0;//全局(静态)初始化区

14.

15. p1 = (char *)malloc(10);

16. p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。

17.

18. strcpy(p1, "123456");

//123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

19. }

二、动态内存

当程序运行到需要一个动态分配的变量时,必须向系统申请取得堆中的一块所需大小的存储空间,用于存储该变量。当不在使用该变量时,也就是它的生命结束时,要显示释放它所占用的存储空间,这样系统就能对该空间

进行再次分配,做到重复使用有线的资源。下面介绍动态内存申请和释放的函数。

1.1 malloc 函数

malloc函数原型:

[cpp] view plain copy

1. #include

2.

3. void *malloc(size_t size);

size是需要动态申请的内存的字节数。若申请成功,函数返回申请到的内存的起始地址,若申请失败,返回NULL。我们看下面这个例子:

[cpp] view plain copy

1. int *get_memory(int n)

2. {

3. int *p;

4. p = (int *)malloc(sizeof(int));

5. if(p == NULL)

6. {

7. printf("malloc error\n");

8. return p;

9. }

10.

11. memset(p,0,n*sizeof(int));

12. }

使用该函数时,有下面几点要注意:

1)只关心申请内存的大小;

2)申请的是一块连续的内存。记得一定要写出错判断;

3)显示初始化。即我们不知这块内存中有什么东西,要对其清零;

1.2 free函数

在堆上分配的额内存,需要用free函数显示释放,函数原型如下:

[cpp] view plain copy

#include

void free(void *ptr);

使用free(),也有下面几点要注意:

1)必须提供内存的起始地址;

调用该函数时,必须提供内存的起始地址,不能够提供部分地址,释放内存中的一部分是不允许的。

2)malloc和free配对使用;

编译器不负责动态内存的释放,需要程序员显示释放。因此,malloc与free是配对使用的,避免内存泄漏。

[cpp] view plain copy

free(p);

p = NULL;

p = NULL是必须的,因为虽然这块内存被释放了,但是p仍指向这块内存,避免下次对p的误操作;

3)不允许重复释放

因为这块内存被释放后,可能已另分配,这块区域被别人占用,如果再次释放,会造成数据丢失;

版权声明:转载文章来自公开网络,版权归作者本人所有,推送文章除非无法确认,我们都会注明作者和来源。如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜。

c语言静态存储和动态存储,C语言中的静态内存与动态内存相关推荐

  1. python静态变量计数器_如何在Python中使用静态变量在计数

    今天,在用Python写一个统计一个文件下有多少文件的小标本时,遇到了一个很棘手的问题.如何在Python中使用静态变量来计数.然后,就在网上一通查找,找的方法都是利用类的方法来实现静态变量.说实话没 ...

  2. java 中的静态变量,静态代码块,动态代码块,构造方法执行顺序的深入探究

    要想完全弄懂这个执行顺序,需要我们先了解几个概念. 首先是类加载与对象的构造,类加载就是在第一次调用这个类的时候jvm虚拟机会通过类加载器在一个叫做方法区的逻辑内存中将所要用到的类的信息存放在里边,其 ...

  3. 如何用C语言改变宏定义的大小,C语言中宏定义使用的小细节

    C语言中宏定义使用的小细节 #pragma#pragma 预处理指令详解 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#p ...

  4. 非静态方法可以访问Java中的静态变量/方法吗?

    "非静态方法可以访问静态变量或调用静态方法"是Java中有关静态修饰符的常见问题之一,答案是, 是的 ,非静态方法可以访问静态变量或调用静态方法. Java中的方法. 这没有问题, ...

  5. 【C 语言】内存管理 ( 动态内存分配 | 栈 | 堆 | 静态存储区 | 内存布局 | 野指针 )

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

  6. C语言—静态存储与动态存储

    静态存储和动态存储 变量从变量值存在的时间(即生存期)角度分:静态存储方式和动态存储方式 静态:在编译时确定了固定的内存地址与内存大小,如:函数里的局部变量.全局变量等 动态:由程序控制,运行时主动性 ...

  7. C语言题目——通讯录(静态存储+动态存储)

    目录 通讯录基本要求: 实现功能: 一.打印菜单: 二.联系人信息存储 三.通讯录初始化及功能: 1.静态存储通讯录 (1).通讯录信息: (2).初始化通讯录: (3).通讯录功能: 2.动态存储通 ...

  8. C中静态存储区和动态存储区

    c语言中需要内存来存放数据.而内存主要分为两类:静态存储区和动态存储区. 1.静态存储区 (1)分为数据区(只读数据区(代码区?在linux中又叫文本段.text).读写数据区.data).未初始化区 ...

  9. (五十九)自动存储、静态存储、动态存储

    自动存储: 函数内部定义的常规变量,被称为自动变量,这意味着他们在所属的函数被调用的时候自动产生,在该函数结束时消亡. 自动变量是一个局部变量,作用域为包含他的代码块,比如int main(){}中定 ...

最新文章

  1. Agile Controller产品概述
  2. 拦截导弹 最长上升/下降子序列
  3. 数学建模 匈牙利算法求解整数规划基本原理与编程实现
  4. 转:Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:]
  5. begin entries matlab,Matlab-图形算法和图像处理指南
  6. 第010讲 通配符选择器 父子选择器
  7. 论文笔记_S2D.59_2015-ICRA_V-LOAM_低漂移、鲁棒和快速的视觉-激光 里程计和建图
  8. 什么能让我们用青春、用生命去垫付?
  9. DS18B20引脚 实物引脚 (千万不要接反啊)
  10. go与python的前景_为什么说GO语言是未来前景看好的编程语言
  11. luoguP3403 跳楼机
  12. Kali使用beef
  13. 工欲善其事,必先利其器——学会不将就,让自己事半功倍!
  14. 微信默认表情符号的代码对照表
  15. 基于labview开发平台的声音信号采集及处理系统设计(任务书+lunwen+翻译及原文+vi源文件+查重报告)
  16. Android(一)
  17. Linux 终端 基本指令
  18. 云原生docker容器创建实操
  19. [python] 使用Jieba工具中文分词及文本聚类概念
  20. stm32 flymcu开始连接... 接收到:7F 7F 7F 7F 7F 7F以及无跳线帽短接方法

热门文章

  1. matplotlib全图
  2. python项目实战:20行代码画一朵好看又有趣的小花花
  3. javax.swing.jFrame
  4. 智慧城市资金瓶颈亟待突破
  5. 基于CORS的geoserver同源访问策略
  6. 也说_T、_TEXT、TEXT、L
  7. [CLR via C#]17. 委托
  8. 面试官三连问:分库分表了解吧?业界有哪些常用方案?可能存在什么问题?
  9. 基于SSM实现个人健康管理系统
  10. hbctraining-05_peak_calling_macs2