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

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

一、动态内存分配

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

//numNumber of elements.

  sizeLength in bytes of each element.

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

4、realloc函数

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

函数原型:

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

memblockPointer to previously allocated memory block.

sizeNew 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]);

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容