2012-03-12 47 views
1

读到这里,我怎么malloc的内存malloc/free。可以从释放的内存

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); 我的意思是为什么它可以遍历在解放后?

我是否正在以这种方式正确地工作,当函数返回一些内存,在另一个上下文中释放?

+2

请参阅http://stackoverflow.com/a/6445794/1025391(标记为C++,但大多数也适用于您的情况) – moooeeeep 2012-03-12 19:48:09

+0

修复代码中的错误并且神秘将消失。 Buggy代码会做出奇怪和不可预知的事情,这并不令人意外。 – 2012-03-12 19:48:45

回答

2

您的程序展示未定义的行为。总之,任何事情都可能发生,包括你的程序出现工作。

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

0

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

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

0

这显然是未定义的行为。

释放内存并不意味着将其归零。大部分时间,内存将 简单地标记为“可用”。正如你在释放后立即使用它,它仍然是完好无损的 。但如果由于某种原因需要更多内存,则可能会覆盖 。

1

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

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

Windows 95的?没问题。好的新的32位API,但它仍然完美地运行了旧的16位软件。微软为此着迷,花费大量的测试来测试他们在Windows 95上可以找到的每一个旧程序。编写Windows 3.x SimCity原始版本的Jon Ross告诉我,他意外地在SimCity中留下了一个bug,在那里他阅读他刚刚释放的记忆。是的。它在Windows 3.x上运行良好,因为内存永远不会去任何地方。以下是令人惊叹的部分:在Windows 95的测试版上,SimCity未在测试中工作。微软追踪了这个错误,并在Windows 95中添加了寻找模拟城市的特定代码。如果它发现SimCity正在运行,它将以一种特殊模式运行内存分配器,该模式不会立即释放内存。这是对向后兼容性的痴迷,使人们愿意升级到Windows 95.

1

从已释放的内存中读取/写入/写入内存是未定义的行为。你的程序今天可能有效,明天就会崩溃;或者等到下一个满月才会崩溃。

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