1.为啥要动态内存管理:
能够灵活的决定申请时机和释放时机;可以在运行时决定内存申请的大小。
2.动态内存函数(标准库提供,其头文件是stdlib.h)
>1.malloc
m(memory/内存)+alloc(allocate/申请)
功能:malloc能够在系统中申请到一块连续的内存。
void*malloc(size_t size);
size表示要申请的字节数,类型是size_t,所以不能是负数,也不能是0。void*表示申请的连续内存空间的起始地址,这个内存空间编译器不知道,它知道是个地址,所以使用malloc的时候,往往需要根据实际情况,把void*强制类型转换成其他咱们需要的类型的指针;如果开辟成功,则返回一个指向开辟好空间的指针。如果开辟失败,则返回一个NULL指针(可能是系统内存不了,也可能是申请的内存空间太大了),因此malloc的返回值一定要做检查。
malloc申请的内存,程序运行如果运行结束,就会和程序一起释放了;程序没有结束的时候,手动调用free函数就释放了。gon
>2.free
void free(void* ptr);
void*ptr这个参数是指malloc返回值的地址,如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的;如果参数 ptr 是NULL指针,则函数什么事都不做。
当我们进行动态内存申请的时候,一定要记得free
>3.calloc
void* calloc(size_t num,size_t size);
第一个参数表示申请多少个元素,第二个元素表示一个元素几个字节,总字节数为num*size。calloc的返回值仍然是一个连续内存空间的起始地址,calloc申请的内存,会被初始化为全0,malloc申请的内存,不会被初始化,内存上的值是随机值。同样,calloc申请的内存也要free。
>4.realloc
功能:针对动态申请的内存,进行扩容。
void* realloc(void* ptr,size_t size);
ptr 是要调整的内存地址,size是 调整之后新大小,返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 新 的空间。
realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有足够大的空间,要扩展内存就直接在原有内存之后直接追加空间,原来空间的数据不发生变化。情况2:原有空间之后没有足够大的空间,在堆空间上另找一个合适大小的连续空间来使用,就会把之前申请的内存一同搬运过去,这样函数返回的是一个新的内存地址。