绝不能对非动态分配存储块使用free,也不能对同一块内存区同时用free释放两次,为啥?free函数原理是?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了绝不能对非动态分配存储块使用free,也不能对同一块内存区同时用free释放两次,为啥?free函数原理是?相关的知识,希望对你有一定的参考价值。

动态内存也就是堆区,非动态内存也就是栈区

栈是系统管理的,当然不能free

你申请内存时,实际上系统是把一块标记为未使用的内存地址返回给你,然后把那个地址标记为已使用。

你释放的时候,实际上就是把那块内存标记为未使用。

你要对一个已经标记为未使用的内存再标记成未使用,当然就不可以了!
参考技术A 操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的malloc申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。

free:释放ptr指向的存储空间。被释放的空间通常被送入可用存储区池,以后可在调用malloc、realloc以及realloc函数来再分配。
free两次不一定出问题,看人品。最好不要free两次追问

free两次不一定出问题,我也觉得这样!那是教材上说的了,我觉得应该说是“不能对同一块已分配的内存区连续free一次以上”。看来free的原理就像你说的那样,如果那样,那么对同一块已分配的内存区连续free一次以上可能产生的最严重的后会是什么呢?操作系统会终止程序往下运行?还是操作系统会崩溃,然后死机?你觉得呢?

追答

结果未定义,要看内存的实际情况了

参考技术B free是释放程序开发人员,开辟的内存。操作系统为程序分配的内存,由操作系统管理,开发者不应处理。

动态内存分配

free的用法:

(1)free不能只释放一部分内存,是释放一整块开辟的内存

(2)free不能释放非动态开辟的内存

    int a=10;

    int*p=&a;

    free(p); 错误

(3)free不能释放多次内存

    int*ptr1=p;

    int*ptr2=p;

    free(ptr1);

    free(ptr2); 错误

Malloc:

#include<stdio.h>
#include<stdlib.h>
int main()
{
int*p = (int*)malloc(10 * sizeof(int));
int i = 0;
if (p == NULL)
{
printf("out of memory\n");
exit(0);
}
for (i = 0; i < 10; i++)
{
p[i] = i + 1;
}
for (i = 0; i < 10; i++)
{
printf("%d ", p[i]);
}
printf("\n");
free(p);
getchar();
return 0;
}

结果:1 2 3 4 5 6 7 8 9 10

封装成函数:

#define MALLOC(count,type)(type *)malloc(count*sizeof(type))//封装
int main()
{
int*p = MALLOC(10,int);//调用,不用判断p=NULL
int i = 0;
for (i = 0; i < 10; i++)
{
p[i] = i+1;
}
for (i = 0; i < 10; i++)
{
printf("%d\n", p[i]);
}
free(p);
getchar();
return 0;
}
Calloc:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int*p = (int*)calloc(100,sizeof(int));
int i = 0;
int*q = NULL;
for (i = 0; i < 100; i++)
{
p[i] = i + 1;
}
q = realloc(p, 200 * sizeof(int));
for (i = 0; i < 200; i++)
{
printf("%d ", p[i]);
}
printf("\n");
free(p);
getchar();
return 0;
}

例:动态开辟二维数组

#include<stdio.h>
#include<stdlib.h>
int main()
{
int(*p)[4] = (int(*)[4])malloc(3 * 4 * sizeof(int));
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
p[i][j] = i * 4 + j + 1;
}
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%d ", p[i][j]);
}
printf("\n");
}
free(p);
getchar();
return 0;
}

结果:

1 2 3 4

5 6 7 8

9 10 11 12 


以上是关于绝不能对非动态分配存储块使用free,也不能对同一块内存区同时用free释放两次,为啥?free函数原理是?的主要内容,如果未能解决你的问题,请参考以下文章

动态内存分配

动态内存管理

动态内存管理

梦开始的地方—— C语言动态内存管理(malloc+calloc+realloc+free)

动态内存管理详解(动态内存函数介绍 + 常见动态内存错误 + 经典笔试题)

关于动态内存管理的一些理解