动态内存管理
前言
一、动态内存函数
malloc
void* malloc (size_t size);
int* ptr=NULL;
ptr=(int*)malloc(4*sizof(int))//开辟4个int类型大小的空间
if(ptr=NULL)
{
}
free(ptr);
ptr=NULL;
calloc
void* calloc (size_t num, size_t size);//开劈空间并且将开辟的空间全都初始化为0;
realloc
void* realloc (void*ptr, size_t size);
int* ptr=NULL;
ptr=(int*)malloc(4*sizeof(int))//开辟4个int类型大小的空间
if(ptr=NULL)
{
}
int* p=NULL;
p=(int*)realloc(ptr,8*sizeof(int));
if(p=NULL)
{
}
ptr = p;
p=NULL;
free(ptr);
ptr=NULL;
ptr为原来指针,8*sizeof 是增加开辟空间后的总内存
二、动态内存分配常见错误
1.忘记判断分配是否成功
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
2.动态开辟空间越界访问
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);
}
3.对非动态开辟的空间使用free分配
void test()
{
int a = 10;
int *p = &a;
free(p);//不是动态分配的地址
}
4.free没有完全释放空间
void test()
{
int *p = (int *)malloc(100);
p++;//p++以后指针已经不是指在开辟空间的头部
free(p);//释放不完全
}
5.多次释放同一片地址
void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);//重复释放
}
6.内存泄漏
int* ptr=NULL;
ptr=(int*)malloc(4*sizeof(int))//开辟4个int类型大小的空间
if(ptr=NULL)
{
}
int* p=NULL;
p=(int*)realloc(ptr,8*sizeof(int));
if(p=NULL)
{
}
ptr = p;
p=NULL;
//free(ptr);
//ptr=NULL;缺少手动释放内存空间的动作
三、动态开辟的地址存放在堆区
1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结
束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是
分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返
回地址等。
2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分
配方式类似于链表。
3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码。
总结
1.开辟动态内存使用到三个函数
malloc()calloc()realloc()
一个释放空间的函数 free()
2.在日常开辟动态空间时务必规避常见错误,加强代码健壮性