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

一、动态内存分配

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. CodeForces 1327F AND Segments

    题意 给三个整数 \(n,k,m\) 和 \(m\) 个限制 \((l_i,r_i,x_i)\),求有多少个长度为 \(n\) 的序列 \(a\) 满足: 对于 \(1\leq i\leq n\) 有 ...

  2. [Luogu P2257] YY的GCD (莫比乌斯函数)

    题面 传送门:洛咕 Solution 推到自闭,我好菜啊 显然,这题让我们求: \(\large \sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)\in prime]\) 根 ...

  3. MySQL中没有FULL OUTER JOIN的处理

    FULL OUTER JOIN:SELECT column_name(s)FROM table1FULL OUTER JOIN table2ON table1.column_name=table2.c ...

  4. 关于H5页面在微信浏览器中音视频播放的问题

    Android 上,因为各个软件使用的浏览器渲染引擎不一样,所以视频播放的效果差异也很大,这里主要以微信为主.微信使用的是腾讯浏览器自带的X5内核. 而iOS是不允许使用第三方浏览器内核的,就是Goo ...

  5. php 之 excel导出导入合并

    <?php class Excel extends Controller { //直属高校 public function __construct() { parent::Controller( ...

  6. Manacher (马拉车) 算法:解决最长回文子串的利器

    最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...

  7. CSS选择器组合符号

    组合连接符号 无连接符 多项条件 空格符 后代节点 > 子节点 + 兄弟节点 ~ 兄弟节点 这里要注意+和~之间的区别 +是后面紧邻兄弟 ~是后面所有兄弟

  8. linux 信号 ctrl + d z c fg bg 作用

    ctrl+c:前台进程终止 后台进程的终止: 方法一:通过jobs命令查看job号(假设为num),然后执行kill %num   $ kill %1 方法二:通过ps命令查看job的进程号(PID, ...

  9. Socket accept 简要分析

    accept 用于从指定套接字的连接队列中取出第一个连接,并返回一个新的套接字用于与客户端进行通信,示例代码如下 #include <sys/types.h> /* See NOTES * ...

  10. linux 内存泄露 valgrind

    内泄漏工具 valgrind: https://linux.die.net/man/1/valgrind www.valgrind.org/docs/manual/index.html www.val ...