【问题标题】:What happens to memory after free()?free() 之后内存会发生什么变化?
【发布时间】:2020-07-14 09:08:02
【问题描述】:

我知道,在您的硬盘驱动器上,如果您删除文件,数据不会(立即)消失。数据仍然存在,直到被覆盖。我想知道记忆中是否存在类似的概念。假设我为一个字符串分配了 256 个字节,在我 free() 之后,该字符串是否仍然漂浮在内存中,直到它被覆盖?

【问题讨论】:

  • 这和windows有什么关系?你是在专门问windows吗?

标签: c memory dynamic-memory-allocation free


【解决方案1】:

如果您想验证实现的行为,下面的简单程序将为您完成。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* The number of memory bytes to test */
#define MEM_TEST_SIZE 256

void outputMem(unsigned char *mem, int length)
{
    int i;

    for (i = 0; i < length; i++) {
        printf("[%02d]", mem[i] );
    }   
}

int bytesChanged(unsigned char *mem, int length)
{
    int i;
    int count = 0;

    for (i = 0; i < MEM_TEST_SIZE; i++) {
        if (mem[i] != i % 256)
            count++;
    }
    return count;
}

main(void)
{
    int i;
    unsigned char *mem = (unsigned char *)malloc(MEM_TEST_SIZE);

    /* Fill memory with bytes */
    for (i = 0; i < MEM_TEST_SIZE; i++) {
        mem[i] = i % 256;
    }

    printf("After malloc and copy to new mem location\n");
    printf("mem = %ld\n", mem );
    printf("Contents of mem: ");
    outputMem(mem, MEM_TEST_SIZE);

    free(mem);
    printf("\n\nAfter free()\n");
    printf("mem = %ld\n", mem );
    printf("Bytes changed in memory = %d\n", bytesChanged(mem, MEM_TEST_SIZE) );
    printf("Contents of mem: ");
    outputMem(mem, MEM_TEST_SIZE);


}

【讨论】:

    【解决方案2】:

    答案很大程度上取决于实施。在一个好的实现中,至少内存的开头(或结尾?)可能会被簿记信息覆盖,以跟踪以后可以重用的空闲内存块。但是细节会有所不同。如果您的程序具有任何级别的并发/线程(即使在您可能看不到的库实现中),那么这样的内存可能会被异步破坏,甚至可能以这样的方式读取它是危险的。当然,free 的实现可能会从程序的虚拟地址空间中完全取消映射地址范围,在这种情况下,尝试对其进行任何操作都会使您的程序崩溃。

    从应用程序作者的角度来看,您应该根据规范简单地对待free,并且永远不要访问已释放的内存。但从系统实施者或集成者的角度来看,了解(或设计)实施可能很有用,在这种情况下,您的问题就会很有趣。

    【讨论】:

    • 我真的不打算读取我释放的内存,因为我对不确定性和不稳定性也有同样的想法。这个问题只是出于我的好奇。
    【解决方案3】:

    你的比喻是对的。内存中的数据不会消失或类似的东西;在free() 之后,这些值可能确实仍然存在,尽管尝试从释放的内存中读取是未定义的行为。

    【讨论】:

      【解决方案4】:

      一般来说,它确实存在,除非您在 freeing 之前明确覆盖字符串(就像人们有时使用密码一样)。一些库实现会自动覆盖已释放的内存以捕获对其的访问,但在释放模式下不会这样做。

      【讨论】:

      • 这就是我的想法,我想我应该在 free() 之前使用 ZeroMemory 以防止它在释放后被读取。谢谢。
      • @Lienau 如果你想要一些矫枉过正的东西(总是好的:)),你可以使用 DoD 或 Gutmann,但这些是为你的硬盘设计的......
      猜你喜欢
      • 2013-09-06
      • 2014-05-17
      • 2015-06-17
      • 2023-04-01
      • 2023-03-14
      • 2019-09-30
      • 1970-01-01
      • 2016-07-13
      相关资源
      最近更新 更多