动态内存分配
malloc
初始化
#include <stdlib.h>
int main()
{
//动态内存开辟的
int* p = (int*)malloc(10*sizeof(int));
//使用这些空间的时候
if (p == NULL)
{
perror("main");//main: xxxxxxxxx
return 0;
}
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d\n", p[i]);//p[i] --> *(p+i)
}
//回收空间
free(p);
p = NULL;//自己动手把p置为NULL
return 0;
}
使用
#include <stdlib.h>
int main()
{
//int arr[10];//栈区
//动态内存开辟的
int* p = (int*)malloc(10*sizeof(int));
//使用这些空间的时候
if (p == NULL)
{
//printf + strerror
perror("main");//输出错误为main: xxxxxxxxx
return 0;
}
//使用
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", p[i]);
}
//回收空间
free(p);
p = NULL;//自己动手把p置为NULL--必须
return 0;
}
- 开辟10个整形的空间 - - 10* sizeof(int)
- 开辟1
calloc
初始化
#include <stdlib.h>
int main()
{
//动态内存开辟的
int* p = (int*)calloc(10, sizeof(int));
//使用这些空间的时候
if (p == NULL)
{
perror("main");//main: xxxxxxxxx
return 0;
}
//使用
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d\n", p[i]);//p[i] --> *(p+i)
}
//回收空间
free(p);
p = NULL;//自己动手把p置为NULL
return 0;
}
relloc
调整空间
int main()
{
int* p = (int*)calloc(10, sizeof(int));
if (p == NULL)
{
perror("main");
return 1;
}
//使用
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = 5;
}
//这里需要p指向的空间更大,需要20个int的空间
//realloc调整空间
int*ptr = (int*)realloc(p, 20*sizeof(int));
if (ptr != NULL)
{
p = ptr;
}
free(p);
p = NULL;
return 0;
}
- 因为relloc开辟的时候可能返回到旧的地址也有可能返回新的地址所以relloc开辟的时候不能用p,而是需要重新定义一个指针
类似malloc
int main()
{
int* p = (int*)realloc(NULL, 40);//这里功能类似于malloc,就是直接在堆区开辟40个字节
return 0;
}
动态内存开辟常见的错误
- 对NULL指针的解引用操作
- 不确定空间是否开辟成功就进行解引用
int main
{
int*p = (int*)malloc(1000000000);
//对malloc函数的返回值,做判断
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
return 0;
}
- 对动态开辟空间的越界访问
- 只开辟40个字节(可以存放10个整型元素)但是越界访问了40个元素
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
return 1;
}
int i = 0;
//越界访问
for (i = 0; i < 40; i++)
{
*(p + i) = i;
}
free(p);
p = NULL;
return 0;
}
- 对非动态开辟内存使用free释放
int main()
{
int arr[10] = { 0 };//栈区
int* p = arr;
//使用
free(p);//使用free释放非动态开辟的空间
p = NULL;
return 0;
}
- 使用free释放一块动态开辟内存的一部分
int main()
{
int* p = malloc(10 * sizeof(int));
if (p == NULL)
{
return 1;
}
int i = 0;
for (i = 0; i < 5; i++)
{
*p++ = i;
}
free(p);
p = NULL;
return 0;
}
- 对同一块动态内存多次释放
int main()
{
int* p = (int*)malloc(100);
//使用
//释放
free(p);
p = NULL;
//释放
free(p);
return 0;
}
- 动态开辟内存忘记释放(内存泄漏)
- 在这里p未在函数中销毁(不能在主函数中释放),就算p销毁不要担心malloc开辟的空间会销毁,因为malloc它自己用完会释放
void test()
{
int* p = (int*)malloc(100);
if (p == NULL)
{
return;
}
//使用
}
int main()
{
test();
//....
return 0;
}