在编写程序时,通常并不知道需要处理的数据量,或者难以评估所需处理数据量的变动程度。在这种情况下,要达到有效的资源利用——使用内存管理,必须在运行时动态地分配所需内存,并在使用完毕后尽早释放不需要的内存,这就是动态内存管理原理。动态内存管理同时还具有一个优点:当程序在具有更多内存的系统上需要处理更多数据时,不需要重写程序。

一、动态内存分配

1、malloc函数

能够在堆中动态地分配一块指定大小的内存空间。malloc中文叫 动态内存分配 ,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间 ,就需要用到动态的分配内存,且分配的大小就是程序要求的大小。

函数原型:

void* malloc(unsigned int size);

返回:返回一个指向被分配的内存块起始位置

失败返回NULL指针,说明没有分配成功。

2、泛型指针

void*

相同类型的指针可以相互转化,泛型指针就是:可以转化成任何类型的指针

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

if (p != NULL)

{

printf("动态开辟内存成功.\n");

}

else

{

printf("失败\n");

}

*p = 45;

char *p1=malloc(sizeof(char));

*p1 = 'A';

//是分配的一块连续的内存空间

3、calloc函数

有时候,我们在程序中需要一段内存来处理数据,但是又不确定是要多大内存的情况下,比如 我们申请一个数组 a[100] 但是事前我们并不知道会不会用得完这100个元素,比如我们只会用到10个,那么剩下的90个就会还在占用空间,就显得很浪费空间,这时候使用calloc函数是用来在内存的 动态存储 区中(堆中)分配一个连续存储空间。

//函数原型:

void *calloc( size_t num , size_t size);

//分配的这块空间 会被初始化为0

//num Number of elements.

size Length in bytes of each element.

//效率: malloc效率要高,calloc还要将里面初始化为0.

4、realloc函数

用于修改原先已经分配好了的内存空间大小,realloc()函数可以重用或扩展以前用malloc()、calloc()及realloc()函数自身分配的内存。

函数原型:

void *realloc( void *memblock , size_t size);

memblock Pointer to previously allocated memory block.

size  New size in bytes.

//扩大:

//缩小:

5、内存释放

free();

//函数原型

void free(void *memblock);

int *p=malloc(sizeof(int) * 5);

p[0] = 11;

p[1] = 22;

p[2] = 33;

p[3] = 44;

p[4] = 55;

for (int i = 0; i < 5;i++)

{

printf("%d\t",p[i]);

}

printf("\n");

//释放这块内存空间

free(p);

//p野指针  指向一块非法的内存空间

6、内存泄漏

对于任何使用 C 语言的人,如果问他们 C 语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏。

在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。

在C++中出现内存泄露的主要原因就是程序猿在申请了内存后(malloc(), new),没有及时释放没用的内存空间,甚至消灭了指针导致该区域内存空间根本无法释放。

知道了出现内存泄露的原因就能知道如何应对内存泄露,即:不用了的内存空间记得释放!

内存泄漏可能会导致严重的后果:
●  程序运行后,随着时间占用了更多的内存,最后无内存可用而崩溃;
●  程序消耗了大量的内存,导致其他程序无法正常使用;
●  程序消耗了大量内存,导致消费者选用了别人的程序而不是你的;
●  经常做出内存泄露bug的程序猿被公司开出而贫困潦倒。

如何检测内存泄露

观察内存泄露是一个两步骤的过程。首先,使用swap命令观察还有多少可用的交换空间:

/usr/sbin/swap -s

total:17228K bytes allocated + 5396K reserved=22626K used,29548K available.

在一两分钟内键入该命令三到四次,看看可用的交换区是否在减少。还可以使用其他一些/usr/bin/*stat工具如netstat、vmstat等。如发现波段有内存被分配且从不释放,一个可能的解释就是有个进程出现了内存泄露。

7、内存操作函数

#include <string.h>

memcpy()

memmove()

memchr()

memset()

//-----------

int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int arr1[10];

//memcpy(arr1,arr,sizeof(arr));

memset(arr1,0,40);

for (int i = 0; i < 10;i++)

{

printf("%d\n",arr1[i]);

}

如果你也想要自学C语言,接受全面系统的指导。这里有一个交流群推荐给你。不论是小白还是进阶者,在这里都能获得成长。群内含有,学习书籍电子书资源,素材包,还有免费教学课程哦~

C语言精华——内存管理,很多学校学习不到的知识~的更多相关文章

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

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...

  2. C语言的内存管理

    C语言的内存管理 转载:http://blog.csdn.net/wind19/article/details/5964090   对于一个C语言程序而言,内存空间主要由五个部分组成代码段(.text ...

  3. R语言之内存管理

    转载于:http://blog.csdn.net/hubifeng/article/details/41113789 在处理大型数据过程中,R语言的内存管理就显得十分重要,以下介绍几种常用的处理方法. ...

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

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...

  5. C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针

    C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针 (1)开辟的内存没有释放,造成内存泄露 (2)野指针被使用或释放 (3)非法释放指针 (1)开辟的内存没有释放.造成内存泄露,以下的样 ...

  6. c语言之内存管理

    在计算机系统,特别是嵌入式系统中,内存资源是非常有限的.尤其对于移动端开发者来说,硬件资源的限制使得其在程序设计中首要考虑的问题就是如何有效地管理内存资源.本文是作者在学习C语言内存管理的过程中做的一 ...

  7. 内存管理——linux内核学习

    买了<深入Linux内核架构>这本书准备了解一下linux内核机制.但是最开始看了十几页感觉看着很累,本来都准备弃了 过了段时间看见一个面经有linux内核的内容,于是就照着那个先把内存管 ...

  8. 内存管理之三——Cocos2d-x学习历程(七)

    1.容器---2.0版本 Cocos2d-x引擎为我们提供了CCArray.CCDictionary等Objective-C风格的容器.使用Cocos2d-x容器的一个重要原因在于Cocos2d-x的 ...

  9. object-c 内存管理机制的学习

    1.内存的创建和释放 让我们以Object-c世界中最最简单的申请内存方式展开,谈谈关于一个对象的生命周期.首先创建一个对象: //“ClassName”是任何你想写的类名,比如NSString NS ...

随机推荐

  1. 走在深夜的小码农 Sixth Day

    Css3 Six Day writer:late at night codepeasant 学习大纲: 一.其他样式 1.圆角边框 在 CSS3 中,新增了圆角边框样式,这样我们的盒子就可以变圆角了. ...

  2. mysql报错10061和10038

    用navicat连接报错10038,用sqlyog报错10061,又去查看服务,发现服务丢失 经过一系列的查阅资料,用下面的方式解决了问题 1.用管理员的方式打开命令行窗口 2.进入mysql的bin ...

  3. DTU是怎么与PLC连接通信的

    数据采集是生产制造中最实际最频繁的需求,不管智能设备制造发展到何种程度它都是工业4.0的先决条件,也在数字化工厂当中,工人更多地是处理异常情况,调整设备.但数据采集一直是困扰着所有制造工厂的传统痛点, ...

  4. freopen ()函数

    1.格式 FILE * freopen ( const char * filename, const char * mode, FILE * stream ); 2.参数说明 filename: 要打 ...

  5. 什么是SPI

    一.什么是SPI SPI ,全称为 Service Provider Interface,是一种服务发现机制.它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加 ...

  6. python爬虫01在Chrome浏览器抓包

    尽量不要用国产浏览器,很多是有后门的 chrome是首选 百度 按下F12 element标签下对应的HTML代码 点击Network,可以看到很多请求 HTTP请求的方式有好几种,GET,POST, ...

  7. 小规模DES手写加解密

    1.加密 2.解密

  8. efcore 学习

    新开一个博客来写一下ef core的学习过程 这个博客内容会跟着官网走 具体可见官网https://docs.microsoft.com/zh-cn/ef/core/get-started/?tabs ...

  9. 17flask分页

    一,flask_sqlachemy的使用 如果想要展示出来的页面是分页显示,则首先需要知道每页应该分多少个条目,然后通过数据库去查找对应的条数,同时也需要和分页所需的"paginate&qu ...

  10. 深度学习中的Dropout

    dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃.注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络. ...