关于malloc与free的一些探索

   欲解决问题:“malloc得到的内存在free后是否真的释放给了OS?”

   我们都知道,当一个进程开始运行时,操作系统会分配给它一块堆空间,而当程序中执行malloc操作时,会从这块堆空间中拿到一块连续的内存空间,当我们对这块内存进行free操作后,这块内存还给了这个进程,但是这个进程依旧可以对这块空间进行操作,因为这块空间本来就是属于这个进程的堆空间。free之后,这个进程中可能会再malloc使用到这块空间,所以使用已经free掉的空间是危险的。

   下面我们来看一段代码:

   

#include<stdio.h>
#include <stdlib.h>

int *lvret(void) {
    int ret = 5;
    return &ret;
}

void mod(void) {
    int a = 7;
}

int main(void) {
    int *p = lvret();
    mod();
    printf("%d\n",*p);
	*p=2;
	printf("%d\n",*p);
}
    在上面这段代码中,在调用完lvret函数后,ret这块空间已经相当于free掉了,但返回的指针保存了这块内存的地址。随后又调用了mod函数,其中也定义了一个变量(相当于malloc),最后结果打印出来是 “7”和“2”
说明之前的内存虽然free掉了,甚至已经被别的函数拿去使用了,但依旧可以访问到它甚至对其进行操作。
    由此至此我们可以有一个小结论:free后的内存空间不是真正还给了操作系统,准确点说是还给了这个进程,因为free后这块内存是无法被其他进程使用的,而且依旧可能对其访问和操作(但这是危险的),所以并不是真正意义上的归还。


接下来我们尝试在不同操作系统平台上测试malloc和free操作的不同
以下是进行测试的代码:
int main
{
	int *p = malloc(4);
	printf("The adressis: %d\n",p);
	*p = 5;
	printf("Before free: %d\n",*p);
	free(p);
	printf("After free: %d\n",*p);
	*p = 7;
	printf("Re:%d\n",*p);
	int *q=malloc(4);
	printf("The q adressis: %d\n",q);
	printf("The another malloc q: %d\n",*q)'
	return 0;

}
执行以上代码后,在Linux操作系统上的输出结果如下:

分析:
malloc一片空间时,系统不会自动帮你把这块空间清零;
free一片空间时,系统会自动帮你清零;
通过malloc得到的空间在free后,依旧可以对其进行访问、赋值,而且在free后重新malloc可以得到free掉的那块空间, 这也进一步验证了malloc是从进程的堆空间申请内存,归还也是还到堆空间去。
我创建了另外一个进程2,去访问进程1malloc到的空间,出现段错误。

执行以上代码后,在Windows操作系统上的输出结果如下:

分析:
结果基本和linux平台下的一样,唯一的不同就是在windows环境下,当malloc一片空间时,OS会重新在这块地方填入随机数, 而不像linux下只有在free时才将这块空间清零。






待续……

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页