在编写程序时,通常并不知道需要处理的数据量,或者难以评估所需处理数据量的变动程度。在这种情况下,要达到有效的资源利用——使用内存管理,必须在运行时动态地分配所需内存,并在使用完毕后尽早释放不需要的内存,这就是动态内存管理原理。动态内存管理同时还具有一个优点:当程序在具有更多内存的系统上需要处理更多数据时,不需要重写程序。
一、动态内存分配
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]);
}
如果你想提升你的编程能力,以便更好从事编程类工作的话!那么你很幸运~分享(源码、项目实战视频、项目笔记,基础入门教程)欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!