malloc、realloc、calloc、free动态内存管理

目录

一、malloc

二、realloc

三、calloc

四、free

五、常见的动态内存错误


一、malloc

(1)函数声明

void* malloc (size_t size);

(2)函数作用

在内存的动态存储区中分配一段长度为size字节的连续空间,返回该空间的首地址。(不会被初始化)

1、如果开辟成功,则返回开辟好空间的首地址。

2、如果开辟失败,则返回NULL,因此一定要对malloc的返回值做检查。

3、如果size为0, 返回值取决于特定的库实现(可能是空指针,也可能不是),但是不能对       其进行解引用。

二、realloc

(1)函数声明

void* realloc (void* ptr, size_t size);

(2)函数作用

给一个已分配的空间的指针重新分配内存块,如果条件允许就原地改变,不够就重新分配一个空间,数据拷贝过去,返回新开辟空间的首地址。

1、如果参数ptr为空指针,则其功能和malloc函数类似。分配一段长度为size字节的连续空间,返回该空间的首地址。

realloc调整内存空间的两种情况如下:

        1️⃣情况一:原有空间之后有足够大的空间(原地改变)

         2️⃣情况二:原有空间之后没有足够大的空间

                                          注:在情况二下,原来的数据会被拷贝过去,原来的空间会被自动释放返回的是一个新地址。

三、calloc

(1)函数声明

void* calloc (size_t num, size_t size);

(2)函数作用

为一个包含num个元素的数组分配内存块,每个元素的大小为size字节长,并将其所有位初始化为0,返回该空间的首地址。

1、与malloc函数的区别在于,calloc函数会在在返回地址之前会把申请到的空间的每个字节       初始化位0。

2、如果size为0, 返回值取决于特定的库实现(可能是空指针,也可能不是),但是不能对       其进行解引用。

四、free

(1)函数声明

void free (void* ptr);

(2)函数作用

释放被malloc、realloc、calloc所分配的内存块,使其可再次用以进一步的内存分配。

1、如果参数ptr指向的不是由上面的函数动态开辟的空间,那么free函数的行为是未定义的。

2、如果参数ptr是空指针(NULL),则函数什么事情也不做。

五、常见的动态内存错误

(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(-1);
}
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);//p不再指向动态内存的起始位置
}

(5)对同一块动态内存多次释放

void test()
{
int *p = (int *)malloc(20);
free(p);
free(p);//重复释放
}

(6)动态开辟内存忘记释放(内存泄漏)

void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while(1);
}

        注:忘记释放不再使用的动态开辟的空间会造成内存泄漏。 切记: 动态开辟的空间一定要释放,并且正确释放 。
 

猜你喜欢

转载自blog.csdn.net/weixin_58250064/article/details/125688288