这里我是怎样的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);
之后正常工作
我的意思是为什么在释放后可以进行迭代?
我正在以这种方式做正确的事情,当函数返回一些内存时,它会在另一个上下文中被释放?
答案 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)
这显然是未定义的行为。
释放内存并不意味着将其归零。大多数时候,记忆会 只需标记为“可用”。当你在释放后立即使用它时,它仍然存在 完好无损。但如果由于某种原因需要更多的内存,它可能会 被覆盖。