gpt4 book ai didi

c - free() 如何影响堆上的内存地址?

转载 作者:太空狗 更新时间:2023-10-29 16:35:38 28 4
gpt4 key购买 nike

这个赋值要求我们使用malloc()分配两个int类型的变量(命名为var1var2),打印地址每个变量(指针在栈上的地址和堆上的地址),然后使用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);

}

此代码产生此输出:

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

如您所见,当我释放 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

(明确一点,我所做的只是从之前的代码中删除了 free(var1),所以“AFTER DEALLOCATING var1”部分现在显示的堆地址与之前的设置完全相同,但它确实改变了第三部分中 var1 的堆地址。)

谁能告诉我这里发生了什么?我能想到的唯一合乎逻辑的解释是,当我使用 free() 解除分配 var1 然后打印地址时,它只是打印它的最后一个地址指向,然后当我第二次为 var1 分配内存时,它只是用 var1 的新值“回填”以前的地址。这有意义吗?我的代码中是否有错误,或者这就是 C 在为变量释放内存然后重新分配时的行为方式?

最佳答案

当内存被释放然后重新分配时,malloc 可能返回相同的地址是完全正常的。返回不同的地址也是正常的。

如果您更改 malloc 调用以请求与原始分配不同的大小,您可能会得到不同的地址,因为 malloc 准备的旧 block 可能不够新的要求。但它们可能就足够了,所以地址可能不会改变。

顺便说一句:

  • void main() 不正确。它应该是 int main(void)
  • C 标准不支持在地址指向的空间被释放后打印地址。它“起作用”并不少见,但这是不合适的。 C 2018 6.2.4 2 告诉我们“当指针指向(或刚刚过去)的对象达到其生命周期结束时,指针的值变得不确定。”当用 malloc 分配的对象被用 free 释放时,它的生命周期结束。

关于c - free() 如何影响堆上的内存地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52951210/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com