一. 进程空间

二.进程空间图示

  程序被加载到内存以后,0-4G的内存空间。这0-4G内存中的布局如下图:

三. 栈内存

1.栈存储的特点:

  栈的大小并不大,他的意义并不在于存储大数据,而在于数据交换。

例:

2.常见栈溢出原因:局部变量过多,过大;或递归层数太多。

四. 堆内存

1.堆存储的特点:堆内存可以存放任意类型的数据,但需要自己申请与释放。
2.堆大小,想象中的无穷大(对于栈来说),大空间申请,唯此,无它耳。但实际使用中,受限于实际内存的大小和内存是否连续性。
3.堆内存的申请与释放:

例1:malloc

附例1代码:

//小问学编程
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{//申请基本数据类型和数组,栈堆空间作对比int a;int* p=&a;a=100;printf("*p=%d\n",a);int* pm=(int*)malloc(sizeof(int));if(pm==NULL)return -1;*pm=100;printf("pm=%d\n",*pm);//申请基本数据类型和数组,栈堆空间作对比int array[10];int* pa=array;pm=(int*)malloc(10*sizeof(int));//memset(pm,0,10*sizeof(int));//memset(pm,0,10*sizeof(int));此时会导致什么样的结果呢?for(int i=0;i<10;i++){printf("%d\n",pm[i]);}free(pm);return 0;
}

附:memset是计算机中C/C++语言初始化函数。作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。

补充:

例2:calloc

附例2代码:

//小问学编程
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{int* array=(int*)calloc(10,sizeof(int));for(int i=0;i<10;i++){printf("%d\n",array[i]);//已被初始化}return 0;
}

例3:realloc

附例3代码:

//小问学编程
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{int* array=(int*)calloc(10,sizeof(int));int* newArray=realloc(array,30);//array=realloc(array,30);if(newArray==NULL){printf("realloc 失败\n");return -1;}for(int i=0;i<20;i++){printf("%d\n",newArray[i]);}return 0;
}

free

例4:free

附例4代码:

//小问学编程
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{int* array=(int*)calloc(10,sizeof(int));free(array);return 0;
}

五. 应用模型

例5:之前VLA变长数组,在运行时,只有一次初始化其长度的机会,且容易发生栈溢出。现在有了堆空间的动态申请与释放,动态数组,就成了真正意义上的动态数组了。

附例5代码:

//小问学编程
#include <stdio.h>int main()
{int len;printf("pls new len:");scanf("%d",&len);int* p=(int*)realloc(NULL,sizeof(int)*len);for(int i=0;i<len;i++){printf("%d\n",p[i]);}//加大printf("pls new len:");scanf("%d",&len);p=(int*)realloc(p,sizeof(int)*len);for(int i=0;i<len;i++){printf("%d\n",p[i]);}//变小printf("pls new len:");scanf("%d",&len);p=(int*)realloc(p,sizeof(int)*len);for(int i=0;i<len;i++){printf("%d\n",p[i]);}free(p);return 0;
}

六. 常见错误案例剖析


6.1 置空与判空

例:

6.2 重复申请

6.3 谁申请谁释放模型(并非绝对)

七. 开放的地址空间

  传对象的地址到不同的作用域,可依据地址修改地址所指向对象的内容,根本原因是地址空间是开放的。

八. 栈空间不可以返回

例6:

附例6代码:

//小问学编程
#include<stdio.h>
//1.数值是可以返回的
//2.地址也是可以返回的
//3.栈上的空间不可以返回,原因:随用隋开,用完即消
//4.堆上的空间,是可以返回的。
int func()
{int a=500;return a;
}
int* foo()
{int b=400;int *pa=&b;printf("&a=%p\n",pa);return pa;
}int *func2()
{int arr[100];return arr;
}int main()
{int a=func();printf("a=%d\n",a);int* pa=foo();printf("pa=%p\n",pa);printf("%d\n",*pa);*pa=300;return 0;
}

九. 堆空间可以返回

例7:

附例7代码:

//小问学编程
#include<stdio.h>
//1.数值是可以返回的
//2.地址也是可以返回的
//3.栈上的空间不可以返回,原因:随用隋开,用完即消
//4.堆上的空间,是可以返回的。
char* getFormatMem(int size,char content)
{char* p=(char*)malloc(size *sizeof(char));if(NULL==p)exit(-1);memset(p,content,size *sizeof(char)-1);p[size *sizeof(char)-1]='\0';return p;
}
int main()
{char* p=getFormatMem(20,'a');printf("p=%s\n",p);free(p);return 0;
}

C语言之内存管理初探:栈和堆、malloc、calloc、realloc、free相关推荐

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

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

  2. C语言 内存管理之栈

    内存管理之栈 什么是栈 栈管理内存的特点(小内存.自动化) 栈的应用:局部变量 栈的约束 关于栈的感悟 什么是栈 1.栈是一种数据结构,C语言中使用栈来保存局部变量.栈是管理内存的. 栈管理内存的特点 ...

  3. C语言的内存管理(堆,栈,代码段,数据段)

    C语言的内存管理(堆,栈,代码段,数据段) 一.几个基本概念 在C语言中,关于内存管理的知识点比较多,如函数.变量.作用域.指针等,在探究C语言内存管理机制时,先简单复习下这几个基本概念: 1.变量: ...

  4. JVM内存管理------JAVA语言的内存管理概述

    转载自  JVM内存管理------JAVA语言的内存管理概述 引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上 ...

  5. C语言 --- 动态内存管理(上)+优化版通讯录+笔试题

    文章目录 前言 一.为什么存在动态内存分配 二.动态内存函数的介绍 2.1.malloc函数+free函数 2.2.calloc函数+free函数 2.3.realloc函数 三.常见的动态内存错误 ...

  6. C语言动态内存管理和动态内存分配函数

    给变量分配内存空间可分为静态内存分配和动态内存分配. 静态内存分配属于编译时给变量分配的空间,动态分配属于在程序运行时给变量分配的空间 静态分配属于栈分配,动态分配属于堆分配 运行效率上,静态内存比动 ...

  7. c语言释放内存函数,【C语言】内存分配函数malloc/ calloc/ realloc及内存释放free

    前言: 内存区域划分与分配: 1.栈区(stack)--程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等,程序结束时由编译器自动释放. 2.堆区(heap) -- 在内存开辟另一块存储区域 ...

  8. C语言动态申请内存空间之malloc(),calloc(),realloc()函数

    在C语言中用于动态申请内存空间的函数主要为malloc()函数,calloc()函数,以及realloc()函数,以下主要介绍三个函数的用法,区别以及使用时的注意事项. malloc(),calloc ...

  9. 内存分布malloc/calloc/realloc/free/new/delete、内存泄露、String模板、浅拷贝与深拷贝以及模拟string类的实现

    内存分布 一.C语言中的动态内存管理方式:malloc/calloc/realloc和free 1.malloc: 从堆上获得指定字节的内存空间,函数声明:void *malloc (int n); ...

最新文章

  1. BIEE建模 之 Administration 导入元数据时无法显示表
  2. 相参、相参积累和相参雷达
  3. Software Engineering | Factory method pattern
  4. jquery:使用 SoundManager 2 创建简单的网页音频播放器
  5. 超级玛丽地图java_超级玛丽3全关地图
  6. 数据结构C语言实现动态顺序表
  7. 大数据_MapperReduce_协处理器_类似Mysql的触发器---Hbase工作笔记0024
  8. AJAX不能访问MVC后台程序的问题
  9. java wifi 对讲机_freevoice(局域网对讲机)——Android4项目实战视频教程 - 移动编程 - 私塾在线 - 只做精品视频课程服务...
  10. H3C的发展历史和与华为的关系
  11. Python爬虫实战:1000图库大全【别轻易点进来】
  12. PHP 大地坐标系转高德经纬度
  13. H3CNE综合小实验
  14. C3 linearization
  15. CSDN博客给我带来的一些诱惑和选择机会
  16. Dapr+Net6 服务调用02:本地负载均衡(self-hosted)
  17. 《哪吒》票房直指40亿,闯中国影史前三!导演饺子:最怕你的梦想只有一腔热血...
  18. svn提交代码报错:A conflict in the working copy obstructs the current operation,解决办法
  19. vue字符云-------把老婆放到云端
  20. Windows下jmeter使用

热门文章

  1. 函数声明和函数表达式
  2. python基础教程博客_python基础教程(十)
  3. 基于JAVA+SpringBoot+Mybatis+MYSQL的后台医疗管理系统
  4. java请求报错(原因:CORS 头缺少 ‘Access-Control-Allow-Origin‘)
  5. django解决:ModuleNotFoundError: No module named ‘django.core.urlresolvers‘
  6. yntaxError: Non-UTF-8 code starting with ‘\xe6‘ in file
  7. C#中ref与out使用小结
  8. 3.2 Lucene实战:一个简单的小程序
  9. 获取Python安装目录
  10. 微课|中学生可以这样学Python(5.6.1节):列表推导式2