gpt4 book ai didi

c++ - 关于编译器及其工作方式的问题

转载 作者:IT老高 更新时间:2023-10-28 23:04:08 25 4
gpt4 key购买 nike

这是释放单链表内存的 C 代码。它是用 Visual C++ 2008 编译的,代码可以正常工作。

/* Program done, so free allocated memory */
current = head;
struct film * temp;
temp = current;
while (current != NULL)
{
temp = current->next;
free(current);
current = temp;
}

但我也遇到过(甚至在一本书中)这样写的相同代码:

/* Program done, so free allocated memory */
current = head;
while (current != NULL)
{
free(current);
current = current->next;
}

如果我用我的 VC++ 2008 编译该代码,程序会崩溃,因为我首先释放 current,然后将 current->next 分配给 current。但显然,如果我用其他一些编译器(例如,本书作者使用的编译器)编译这段代码,程序就会工作。所以问题是,为什么用特定编译器编译的这段代码可以工作?是不是因为那个编译器把指令放在二进制文件中,记住 current->next 的地址,尽管我释放了 current 而我的 VC++ 没有。我只是想了解编译器是如何工作的。

最佳答案

第二个程序正在调用未定义的行为。不是编译器的区别,而是C标准库和函数free()实现的区别。编译器会将指针 current 存储为局部变量,但不会存储它所引用的内存的拷贝。

当您调用 free() 时,您放弃了传递给 free() 函数的指针所指向的内存的所有权。在您放弃所有权之后,指向的内存内容可能仍然是合理的,并且仍然是进程地址空间中的有效内存位置。因此,访问它们可能会起作用(请注意,您可以通过这种方式静默破坏内存)。非空指针指向已放弃的内存,称为 dangling pointer。而且非常危险。仅仅因为它看起来有效并不意味着它是正确的。

我还应该指出,有可能以捕获这些错误的方式实现 free(),例如每次分配使用单独的页面,并在调用 free() 时取消映射页面(以便内存地址不再是该进程的有效地址)。这样的实现效率非常低,但有时某些编译器在 Debug模式下使用它来捕获悬空指针错误。

关于c++ - 关于编译器及其工作方式的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2636563/

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