malloc /免费。可以读取释放的内存

时间:2012-03-12 19:43:41

标签: c

这里我是怎样的malloc内存

char *convertToPostfix(char **infixExpr)
{
    char *postfixExpr = (char *) malloc(strlen(*infixExpr) * sizeof(char) * 2);
    ...
    return postfixExpr;
}

这里我如何使用这段记忆:

char *subexpr = convertToPostfix(infixExpr);
free(subexpr);
while (*subexpr) 
    postfixExpr[i++]=*subexpr++;

为什么此程序在free(subexpr);之后正常工作 我的意思是为什么在释放后可以进行迭代?

我正在以这种方式做正确的事情,当函数返回一些内存时,它会在另一个上下文中被释放?

5 个答案:

答案 0 :(得分:2)

您的程序显示未定义的行为。简而言之,任何事情都可能发生,包括您的程序似乎正常工作。

在调用free之后,malloc / free的实现很快就不会将内存块返回到底层操作系统。这是出于性能原因而完成的。通过返回指向您刚刚释放的块的指针并因此重新使用它,可以最有效地处理对malloc的下一次调用。此时,在你的代码中,会有两个指针指向同一块内存,谁知道接下来会发生什么。

答案 1 :(得分:1)

不要使用它!由于程序员依赖于一些声明为未定义的行为,其他程序员应该在以后重现其他错误。

http://www.joelonsoftware.com/articles/fog0000000054.html

  

Windows 95?没问题。不错的新32位API,但它仍然完美地运行旧的16位软件。微软痴迷于此,花了很大一部分变化来测试他们在Windows 95中找到的每个旧程序.Jon Ross编写了原版SimCity for Windows 3.x,告诉我他不小心在SimCity中留下了一个bug。读取他刚刚释放的记忆。是的。它在Windows 3.x上运行良好,因为内存永远不会去任何地方。这是令人惊奇的部分:在Windows 95的beta版本中,SimCity没有进行测试。微软追踪了这个漏洞并在Windows 95中添加了寻找SimCity的特定代码。如果它发现SimCity正在运行,它将以特殊模式运行内存分配器,该模式不会立即释放内存。这种对后向兼容性的迷恋让人们愿意升级到Windows 95。

答案 2 :(得分:1)

从已释放的内存中读取/写入是未定义的行为。你的程序今天可以运行,明天会崩溃;在崩溃之前等到下一个满月。

它似乎工作的原因是因为堆管理器尚未将该内存分配给malloc()的另一个调用方。并且free()没有修改内存的现有内容,因此无论您在调用free()之前写入这些位置的内容仍然存在。但依靠这种行为是一种灾难。

答案 3 :(得分:0)

这是未定义的行为。它似乎有效,但实际上任何事情都可能发生。

它似乎工作(可能)的原因是,当您调用free时,内存不会被清除,而是被操作系统标记为可重复使用。

答案 4 :(得分:0)

这显然是未定义的行为。

释放内存并不意味着将其归零。大多数时候,记忆会 只需标记为“可用”。当你在释放后立即使用它时,它仍然存在 完好无损。但如果由于某种原因需要更多的内存,它可能会 被覆盖。