一、前言
C/C++中内存分配是一个非常重要的话题,主要分为静态分配和动态分配两种。
其中静态分配并不需要我们操心,比如下面这样的代码:
int a;
char buf[100];
这实际上就是在分配一块内存,且是由编译器帮我们分配,会自动完成内存管理,所以我们不需要操心其会造成内存泄漏的问题。
真正需要我们注意的是动态内存分配,同时也是本文所要讲解的重点。
二、malloc与free
首先我们要了解是C语言的内存分配函数malloc
,而free
这个函数就是专门用来释放前者分配的内存的。
看到这里你应该就反应过来了:动态分配的内存是需要我们自己去释放的。
这一点非常的重要,因为如果你忘记了释放就会造成内存泄漏问题。
首先我们还是先来看看它的使用方法:
#include<iostream>
using namespace std;
char* fun(int size) {
char* buf = (char*)malloc(size);
strcpy_s(buf, size, "hello world");
return buf;
}
int main() {
char* buf = fun(100);
cout << buf << endl;
free(buf);
}
上面是一个很简单的示例,但却能与静态内存分配很好的区别开。
首先我定义了一个函数fun
,这个函数的目的是分配指定大小的内存,然后将一个字符串拷贝进去,最后将函数内部分配好的这块内存传出来交给外面打印,最后调用free
函数释放这块内存。
首先注意malloc
函数的使用方法,它只接受一个参数,那就是准备分配多大的内存,以字节为单位,并返回分配好的内存首地址。
char* buf = (char*)malloc(size);
这个地址的类型为void*
,所以可以将其转换为任意我们需要的类型,比如这里将其强制转换为了char*
类型,并将其赋值给了buf
变量。
strcpy_s
函数用于将后面的字符串拷贝到这个缓存区中,最后将这个缓存区地址返回,并且外部函数同样可以使用:
最后再使用free
函数释放这块内存空间。
上面的描述的运行过程中,有几个点是需要特别注意的:
- 内存分配大小是动态传入的。
buf
是在fun
函数中,但将其值返回后,外部函数却依旧能够使用。- 在不需要这块内存时,需要用
free
函数释放。
与之对应的静态分配:
- 内存分配大小必须提前写好。
- 函数内部的变量只能内部使用。
- 不需要手动调用函数释放,因为函数结束后会自动释放。
其中动态分配内存之所以存在,其最重要的原因其实就是第一点,也就是它可以动态调整所要使用内存的大小。
比如当我们写一个程序需要接受用户输入的字符串时,以前可能只能这样做:
char buf[100];
cin>>buf;
这会导致其只能接收指定范围内的字符串,一旦其长度超过了缓存区的长度,就会错误。
而使用动态分配就可以很好的解决这个问题: