目录
1.malloc和free函数的使用方法
malloc函数是动态内存分配函数,用于在堆内存上分配指定大小的内存块。它的使用方法如下:
- 引入stdlib.h头文件,该头文件包含了malloc函数的声明。
- 调用malloc函数,并传入要分配的内存大小作为参数。函数返回一个指向分配内存的指针。
- 使用返回的指针来访问分配的内存,并进行必要的操作。
- 使用完毕后,需要调用free函数释放内存。
free函数用于释放由malloc函数分配的内存。它的使用方法如下:
- 引入stdlib.h头文件,该头文件包含了free函数的声明。
- 调用free函数,并传入要释放的内存块的指针作为参数。
需要注意的是,使用malloc函数分配的内存必须在使用完成后调用free函数释放,以防止内存泄漏。另外,free函数只能释放由malloc函数分配的内存块,对于其他类型的指针或已经释放过的内存块,调用free函数可能导致未定义的行为。
下面是演示代码:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 0;
scanf("%d", &num);
int* p = NULL;
p = (int*)malloc(num*(sizeof(int)));
int i = 0;
if (p != NULL)//判断指针是否为空
{
for (i = 0; i < 5; i++)
{
*(p + i) = i + 1;
printf("%d", *(p + i));
}
}
free(p);//释放p所指向的动态内存
p = NULL;
return 0;
}
2.calloc函数的使用方法
calloc函数用于分配内存空间,并将每个字节都初始化为0。 该函数的使用方法如下:
- 包含头文件:#include <stdlib.h>
- 函数原型:void* calloc(size_t num, size_t size); 参数num表示要分配的元素个数,size表示每个元素的大小。
- 调用函数并将返回的指针赋值给一个指针变量,例如: int* arr = (int*)calloc(10, sizeof(int)); 这样就分配了一个包含10个int类型元素的数组,并将其指针赋值给arr。
- 使用分配的内存空间进行操作,例如: for (int i = 0; i < 10; ++i) { arr[i] = i + 1; } 这样就将数组arr的每个元素依次赋值为1、2、3、...、10。
- 释放内存空间,使用free函数将之前分配的内存空间释放掉,例如: free(arr); 这样就释放了之前分配的数组arr所占用的内存空间。 注意事项:
- 分配的内存空间必须通过free函数手动释放,否则可能会导致内存泄漏。
- 分配的内存空间被初始化为0,如果不需要初始化为0,可以使用malloc函数代替。
下面是代码演示:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 0;
scanf("%d", &num);
int* p = NULL;
p = (int*)calloc(num, sizeof(int));
int i = 0;
if (p != NULL)//判断指针是否为空
{
for (i = 0; i < 5; i++)
{
*(p + i) = i + 1;
printf("%d", *(p + i));
}
}
free(p);//释放p所指向的动态内存
p = NULL;
return 0;
3.realloc函数的使用方法
realloc函数用于重新分配内存空间。它可以用于扩大或缩小已分配的内存块。
realloc的使用方法如下:
void* realloc (void* ptr, size_t size);
其中,ptr是之前分配的内存块的指针,size是重新分配的内存块的大小。
如果ptr为NULL,那么realloc的行为就相当于malloc,即分配一块新的内存块。
如果size为0,那么realloc的行为就相当于free,即释放之前分配的内存块。
如果ptr和size都不为0,那么realloc将尝试重新分配size大小的内存块,并将之前分配的内存块内容复制到新的内存块中。如果重新分配失败,realloc将返回NULL,并保持之前分配的内存块不变。
需要注意的是,realloc返回的指针可能与之前的ptr不同,因此在使用之前需要将返回的指针赋给新的变量。
下面是一个realloc的使用示例:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* ptr = (int*)malloc(20);
if (ptr != NULL)
; //执行语句
else
return 1;
int* p = NULL;
p = realloc(ptr, 10 * sizeof(int));//扩大ptr动态内存的空间
if (p != NULL)
{
ptr = p;
}
free(ptr);//释放ptr动态内存
ptr = NULL;
p = NULL;
return 0;
}
4.动态内存管理的注意事项
1.对NULL指针的解引用操作
void text()
{
int* p = (int*)malloc(INT_MAX / 4);
*p = 20;
free(p);
}
int main()
{
text();
return 0;
}
如果p为NULL,因为NULL是不能被解引用的,就会出现问题,所以我们要判断p是否为NULL.
#include<stdio.h>
#include<stdlib.h>
void text()
{
int* p = (int*)malloc(INT_MAX / 4);
if (p == NULL)
{
perror("malloc");
return 1;
}
*p = 20;
free(p);
p = NULL;
}
int main()
{
text();
return 0;
}
2.对动态空间开辟的越界访问
void text()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
perror("malloc");
return 1;
}
int i = 0;
for (i = 0; i <= 10; i++)
{
*(p + i) = i;//当i是10的时候会发生越界访问
}
free(p);
p = NULL;
}
int main()
{
text();
return 0;
}
如果这样写,就会发生越界访问,导致程序崩溃。
3.对非动态开辟内存使用ferr释放
我们知道ferr只能释放动态内存,而不能去释放其他的内存。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a = 10;
int* p = &a;
free(p);
return 0;
}
如果这样写,也会程序崩溃。
4.使用free释放使用动态开辟内存的一部分
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)malloc(100);
p++;
free(p);
return 0;
}
这样也会发生错误。
5.对同一块内存多次释放
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)malloc(100);
free(p);
free(p);
return 0;
}
这样也会发生错误。
6.动态开辟内存忘记释放(内存泄漏)
#include<stdio.h>
#include<stdlib.h>
void test()
{
int* p = (int*)malloc(100);
if (NULL != p)
{
*p = 20;
}
}
int main()
{
test();
}
所以我们在使用malloc等动态内存函数时一定要使用free来释放动态开辟的空间。