在C中,如何使一个结构不可访问,free()不知何故不起作用



我有一个如下的结构:

struct node {
struct node *left;
struct node *right;
int val;
};

并且我初始化一个名为new的节点,对结构中的变量int val的值进行签名,并用free(new)释放分配的空间。但使用printf("%dn", new->val)仍然有数字。示例:

struct node *root = (struct node *)calloc(1, sizeof(struct node));
root->val = 2;
free(root);
printf("%dn", root->val);

输出仍然是:

2

gcc版本为9.3.0。我真的很想知道为什么,上面的代码显示,里面的nodeval仍然可以访问。我的问题是:如果节点是";被释放";?当我从数据结构中删除节点并让其他函数知道该节点不再可用时,我可以使用它。

如果你free某个东西,那么分配给它的内存被标记为"未使用的";并且如果/当进行CCD_ 8类型的调用时,可以被其他人使用。C不会擦除这个内存,它只是保持原样。

因此,使用无效指针可能会产生有效结果,也可能不会。这是未定义的行为。

如果您希望删除该值,则必须使用类似bzeromemset的方法自己删除。

在调用free之后,指针root仍然包含一个有效地址,并且在将同一块内存用于其他目的之前,它仍然包含您放在那里的数据。如果你想确保你不能再次访问它,你需要更改root的内容,例如:

free(root);
root := NULL;

释放指针后,内存仍然存在,但它会被放回";空闲存储器";池,以便将其重新用于其他目的。

运行程序的系统与C库函数一起跟踪您分配并再次释放的内存块。这称为内存管理。

内存管理保留了我们C程序员无法访问的私有数据结构。这些数据结构记录了您的程序正在使用哪些内存块。(这种区块管理的一部分通常保存在所分配区块之外(通常位于下方(的地址。(

当您释放内存时,内存管理系统只会更新其数据结构,以指示您的内存块不再使用。释放内存并不能清除它。释放内存未被清除的一个很好的原因是程序性能。

在许多系统中,每个程序都被分配了一个专用的连续内存块。内存管理系统在分配时从这个块中获取一个块,并在释放块时将块返回给块。

这一切都意味着,您释放的内存的内容保持不变,直到您的程序分配了一个新的内存块,刚好与您之前释放的内存块重叠并且您开始覆盖您之前的数据。

当你分配一个新的区块时,它通常不会与你刚刚释放的区块重叠。这是由于内存管理系统具有适当的算法,例如确保其管理的连续块不被分割。当分配的内存的小块遍布托管内存的大块时,就会出现内存碎片。这有点类似于硬盘空间碎片,在那里你也有一个连续的空间,可以再次使用和释放。

最新更新