#c语言之动态存储管理
文章目录
1.写在前面的话
大家好,这里是spongebob,今天带来的这篇博客是c语言里的重点,就是动态存储管理。想必每个程序都不陌生吧!话不多说,直接进入主题。如果错误,欢迎在评论区指正。
2.为什么要进行动态内存管理
用于解决数组编译时已开辟的空间内存不够用,我们需要进行动态内存分配。
3.一些常见的动态内存管理函数
-
malloc
函数原型:Void malloc(size_t size)*
函数说明:if successful,malloc() function returns a pointer to the allocated memory, or NULL if the request fails
从代码库中的英文解释中,不难看出在申请动态内存时,是存在申请请求失败的情况。
所以我们都要在使用动态内存前 去验证动态内存是否申请成功(if(xxx!=NULL))。
代码演示:
#include <stdio.h> #include <stdlib.h> int main() { int num = 0; scanf_s("%d", &num); int arr[num] = {0}; int* ptr = NULL; ptr = (int*)malloc(num * sizeof(int)); if (ptr != NULL)//验证是否动态内存申请成功 /*一般来说malloc函数是对内存重新分配空间成功后,不会对其进行初始化,故要对其进行初始化,如下:*/ { int i = 0; for (i = 0; i < num; i++) { *(ptr + i) = 0; } //其实也可以用memset函数,memset函数说明: // ptr ==> Starting address of memory to be filled // x ==> Value to be filled // n ==> Number of bytes to be filled starting // from ptr to be filled //void *memset(void *ptr, int x, size_t n); //代码实现: //int* arr[num]; //arr = (int*)malloc(num * sizeof(int)); //if (arr != NULL) //{ //memset(arr, 0, num * sizeof(int)); } } free(ptr);//记得free!! ptr = NULL; return 0;
-
calloc
函数原型
Void* calloc(size_num , size_t size);
与malloc函数相比,calloc函数得到的内存空间是经过初始化的,其内容全部为0,。所以calloc更适合为数组申请内存空间
代码演示:
#include <stdio.h> #include <stdlib.h> int main() { int* p = calloc(10, sizeof(int)); if (p != NULL) { printf("allocated 10 int integers\n"); } free(p); p=NULL; return 0; }
-
realloc
函数原型:
Void* realloc( void*ptr,size_ size);
函数注意点:
A .realloc 有两种内存开辟方式:
(1)当后续空间足够大,直接在后续空间开辟
(2)当后续空间不够大,重新再堆上申请一块大位置,把原来的内存数据拷贝到新内存之中,原内存被free掉。realloc到了新地址
B.realloc应该保有原有指针
(1)realloc函数 要是没有开辟成功,原来的内存不会改变,不会释放,也不会移动(所以在使用时应该保留原有指针,避免分配时产生内存泄漏。
(传递给realloc的指针必须是malloc()、calloc()、或者realloc()分配的)
代码演示:
#include <stdio.h> #include <stdlib.h> int main() { int* ptr = (int*)malloc(100 * sizeof(int)); if (ptr != NULL) { } else { exit(EXIT_FAILURE); } //错误代码 ptr = (int*)realloc(ptr, 1000 * sizeof(int)); //正确代码 int* p = NULL; p = (int*)realloc(ptr, sizeof(int)); if (p != NULL) { ptr = p; } free(ptr); return0; }
4.malloc/calloc/realloc的区别
相同点
-
都是从==堆上==申请临时空间
-
都需要对返回值判断==是否开辟成功==
-
都需要==free释放==
-
返回值的类型都为==(void *)==
-
都需要进行类型转化
不同点
- 函数名字和参数类型不同
- calloc会向申请的空间初始化为0,而其他的不会
- malloc申请空间必须初始化
- realloc的申请空间调整
5.动态内存错误
A.没有对malloc和calloc的函数进行内存检测
Void test()
{
Int *p=(int*) malloc (10*sizeof (int) );
*p=20;
}
//wrong!
B.对动态开辟的空间进行越界访问
int* newMem = (int*)malloc(400);
memset(newMem, 0xff, 400);
newMem[100] = 0xffffffff;
free(newMem);
//这个数组越界了,系统运行后会报错