目录
一、动态内存分配
1、为什么需要动态内存分配
2.动态内存函数的介绍
2.1 malloc 与 free函数的使用
2.2 calloc函数
2.3 realloc函数
二、动态内存应用中一些常见的错误
1.对NULL指针的解引用操作
2.对动态开辟空间的越界访问
3.对非动态开辟内存使用free释放
4.使用free释放一块动态开辟内存的一部分
5.对同一块动态内存多次释放
6.动态开辟内存忘记释放(内存泄漏)
int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
栈区 | 局部变量 函数的形式参数 |
堆区 | malloc/free calloc realloc 动态内存分配 |
静态区 | 全局变量 静态变量 |
此次我们要学习的动态内存分配相关内容都在堆区。
void* malloc (size_t size);
void free (void* ptr);
示例代码如下:
#include
#include
#include
#include
int main()
{
//申请空间
int * ptr = (int*)malloc(40);
int* p = ptr;
if (p == NULL)
{
perror("malloc");//perror(s) 用来将上一个函数发生错误的原因输出到标准设备(stderr)。
//参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。
return 1;
}
for (int i = 0; i < 10; i++)
{
*p = i;
p++;
}
//释放空间,从哪儿开始申请就从哪儿释放
free(ptr);
ptr == NULL; //断开联系,避免之后非法访问
return 0;
}
调试内存中
申请的空间赋值结束
F10 执行下一行,全部释放
void* calloc (size_t num, size_t size);
int main()
{
//申请10个整型空间
int* p = (int*)calloc(10, sizeof(int));
return 0;
}
运行,调试内存
void* realloc (void* ptr, size_t size);
int main()
{
int* p = (int*)malloc(40);
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + 1) = i;
}
//空间不够,希望放20个元素,扩容,那就是80字节
int* ptr = (int*)realloc(p, 80);
if (ptr != NULL)
{
p = ptr;
}
return 0;
}
注意:以下均为错误示范
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
void test()
{
int i = 0;
int *p = (int *)malloc(10*sizeof(int));
if(NULL == p)
{
exit(EXIT_FAILURE);
}
for(i=0; i<=10; i++)
{
*(p+i) = i;//当i是10的时候越界访问
}
free(p);
}
void test()
{
int a = 10;
int *p = &a;
free(p);
}
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
}
void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);//重复释放
}
void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while(1);
}