我正在测试malloc以了解其行为,并且在操纵后发现了一些奇怪的事情。
我已经进行了3种不同的测试。
首先,我有一个Alloc,并释放我的3 var:
char * a = malloc(10 * sizeof(char));
printf("na = %pn", a);
free(a);
char * b = malloc(10 * sizeof(char));
printf("b = %pn", b);
free(b);
char * c = malloc(10 * sizeof(char));
printf("c = %pnn", c);
free(c);
此显示:
a = 0xd34010
b = 0xd34010
c = 0xd34010
逻辑,它显示相同的地址,记忆空间被回收。
然后,我有Malloc我的3 var,然后免费:
printf("Alloc 3 times and then free :n");
a = malloc(10 * sizeof(char));
printf("na = %pn", a);
b = malloc(10 * sizeof(char));
printf("b = %pn", b);
c = malloc(10 * sizeof(char));
printf("c = %pnn", c);
free(a); free(b); free(c);
它显示我:
a = 0xd34010
b = 0xd34030
c = 0xd34050
a
是合乎逻辑的,因为最后一个c
变量已免费,因此内存空间被重新使用。b
和c
的地址也是逻辑的,因为a
和b
不是免费的,因此地址增加了。
现在,这真的很奇怪。我malloc a,然后b,free a,malloc c和free b and c:
printf("Alloc, free, alloc :nn");
a = malloc(10 * sizeof(char));
printf("a = %pn", a);
b = malloc(10 * sizeof(char));
printf("b = %pn", b);
free(a);
c = malloc(10 * sizeof(char));
printf("c = %pn", c);
free(b); free(c);
结果是:
a = 0xd34050
b = 0xd34030
c = 0xd34050
我的问题是:为什么a
等于0xD34050而不是0xD34010?为什么b
的地址低于a
的地址?
,因为这是在您使用的特定环境中实现内存分配的方式。这听起来可能会翻转,但是拥有这样的例程的全部要点是,他们可以为您照顾簿记。您有更重要的事情要做!
我怀疑您正在在一个程序中执行这些测试,而您正在使用的malloc
实现将维护一些最近杂交的块。
因此,在第一个测试中:
- 第一个
malloc
,需要新的空间,因此给出了0xD34010。 - 0xd34010已释放。
- 通过提供最近的释放块,0xd34010。 来满足第二个
- 0xd34010已释放。
- 第三个
malloc
可以通过提供最近的释放块,0xd34010。 - 0xd34010已释放。
malloc
然后,在第二个测试中:
- 第一个
malloc
可以通过提供最近的释放块,0xd34010来满足。 - 第二个
malloc
需要新的空间,因此给出了0xD34030。 - 第三个
malloc
需要新的空间,因此给出了0xD34050。 - 0xd34010已释放。
- 0xd34030已释放。
- 0xd34050已释放。
然后,在第三个测试中:
- 第一个
malloc
可以通过提供最近的释放块,0xd34050。 - 通过提供最近释放(仍然是免费的)块,0xd34030。 来满足第二个
- 0xd34050已释放。
- 第三个
malloc
可以通过提供最近的释放块,0xd34050。 - 0xd34030已释放。
- 0xd34050已释放。
malloc
当然,这种行为不能由C标准保证。这只是对您在此特定实例中观察到的内容的潜在解释。
您知道printf
还调用malloc
分配流缓冲区吗?在关闭stdout
之前,这些缓冲区不一定要清除。
在打印之前,请尝试单独保存所有指针。
原因可能是
为什么一个等于0xd34050而不等于0xd34010?
您的计算机中的其他一些过程已经占据了地址0xD34010,因此您的编译器为您提供了下一个免费内存。
,到目前为止,我知道,取决于编译器,内存可以按升序或降序分配。它不一定要按升序。
-
它取决于机器。您的编译器的书籍保存常规是这样做的。这可能是由于给予的内存约束。
-
由于您使用了malloc,因此使用堆内存