Dus*_* R. 14 c malloc free heap-memory memory-address
这个赋值要求我们使用malloc()
(命名var1
和var2
)分配两个int类型变量,打印每个变量的地址(堆栈上指针的地址和堆上的地址),然后free()
用来解除分配var1
,再次打印地址,然后在堆中分配另一个空间var1
并第三次打印地址.我相信教师试图告诉我们堆地址var1
应该改变,但它始终保持不变......除非我free(var1)
从代码中删除.教练做了类似的演示,但没有free()
用来解除分配任何变量,所以我们从来没有看到它应该如何工作.
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
void main()
{
int *var1 = (int*)malloc(sizeof(int));
*var1 = 1000;
int *var2 = (int*)malloc(sizeof(int));
*var2 = 2000;
printf("Addresses of var1\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var1, var1);
printf("Addresses of var2\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var2, var2);
free(var1);
printf("AFTER DEALLOCATING var1 FROM THE HEAP\n");
printf("Addresses of var1\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var1, var1);
printf("Addresses of var2\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var2, var2);
var1 = (int*) malloc(sizeof(int));
*var1 = 1500;
printf("NEW MEMORY ADDRESS ALLOCATED FOR var1\n");
printf("Addresses of var1\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var1, var1);
printf("Addresses of var2\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var2, var2);
}
Run Code Online (Sandbox Code Playgroud)
此代码导致此输出:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,堆地址var1
在我解除分配时不会改变,并且当我var1
再次分配内存空间时它不会改变.但是,如果我只是free(var1)
从程序中删除该行,它只是为var1
堆分配第二个内存空间并指向堆上的内存空间,它具有不同的内存地址:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000420
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
Run Code Online (Sandbox Code Playgroud)
(为了清楚起见,我所做的只是free(var1)
从前面的代码中删除,因此"AFTER DEALLOCATING var1"部分现在显示与前一个集合完全相同的堆地址,但它在第三部分中更改了var1的堆地址. )
谁能告诉我这里发生了什么?我能想到的唯一合乎逻辑的解释是,当我free()
用来解除分配var1
然后打印地址时,它只是打印它所指向的最后一个地址,然后当我var1
第二次分配内存时,它只是使用新值"回填"上一个地址var1
.这有意义吗?我的代码中是否有错误,或者这是在为变量释放内存然后重新分配它时C的行为方式?
Eri*_*hil 11
malloc
在释放内存然后重新分配内存时,可能会返回相同的地址,这是完全正常的.它返回不同的地址也是正常的.
如果malloc
将请求更改为请求与原始分配不同的大小,则可能会获得不同的地址,因为旧块malloc
已准备好可能不足以满足新请求.但它们可能就够了,所以地址可能不会改变.
偶然:
void main()
是不正确的.它应该是int main(void)
.malloc
被释放时free
,其生命周期结束.我能想到的唯一合乎逻辑的解释是,当我使用 free() 解除分配 var1 然后打印地址时,它只是打印它指向的最后一个地址
有点对。释放指针根本不会影响指针的内容。或者更准确地说,它被释放后的价值是不确定的。事实上,根据标准,您甚至不能相信指针包含它在调用之前所做的地址free
。据我所知,在大多数情况下它会,但你不能相信它。
标准说:
C 2018 6.2.4 2:“当指针指向(或刚刚过去)的对象到达其生命周期结束时,指针的值变得不确定。”
一个常见的错误是使用测试if(ptr == NULL)
来检查您是否正确释放了指针。这是行不通的。
归档时间: |
|
查看次数: |
1069 次 |
最近记录: |