2011-03-22 138 views
4

我的问题很简单。我们通常通过声明一个指针然后为该指针分配一块内存来分配内存。假设某处代码,我碰巧使用分配和释放内存

ptr = ptr + 1

,然后我用

free(ptr)

谁能告诉会发生什么。整个内存块将被释放或其他东西。我可以部分释放内存吗?

回答

7

必须始终通过相同的指针正好free你从malloc得到(或realloc)。如果你不这样做,“行为是不确定的”,这是一个技术术语,这意味着你可以”不依靠程序以任何可预测的方式行事。不过,在这种情况下,您应该期望它立即崩溃。 (如果运气不好,它会损坏内存,导致一段时间后崩溃,或者更糟糕的是,输出不正确。)

部分释放内存的唯一方法是使用较小尺寸的realloc,但这只适用于修剪最后,并不能保证将修剪过的块用于其他分配。

1

这是不可能的释放部分内存块。你唯一能做的就是重新分配给它不同大小的块。然而,这并不能保证块会落入内存中的相同位置(它可能会复制到其他地方)。

1

您必须传递给free()指向返回的相同位置malloc()的指针。这是因为分配器保留了你分配的块的列表(@everyone:如果我错了,随意添加/修改),如果你传递给free的指针不会比较它的列表free()抱怨( “坏记忆块”也许?)。为了部分释放内存,你应该使用realloc(),它会改变该块内存的大小,但是速度慢并且效率低下。只有在确定新的区块大小或留出更多空间以填补未来时,才应该使用它。

+0

因此,你的意思是分配器保留一个列表,并释放整个块,如果我们释放一个包含该块第一个字节地址的指针? – bubble 2011-03-22 15:27:34

+0

@bubble这是如何得到2 upvotes?从什么时候开始将指针传递给malloc? – 2011-03-22 15:30:46

+0

@bubble:是的,它记得你为每个块分配了多少个字节 – BlackBear 2011-03-22 15:31:05

1

malloc(),free()和realloc()不是C语言的一部分。

这些是在标准库中定义的函数。处理它的标准库中的代码通常称为“分配器”。所以,实际答案是“这取决于C库”。

在Linux上,glibc会使程序崩溃。 在VC++上,C运行时会破坏分配器的状态

源代码可用于这些库,因此您可以实际将断点和步骤放入空闲位置。

+1

调用标准C库“不是[C]语言的一部分”不是错误的*,但会让我感到不适当的细分头发。 – zwol 2011-03-23 19:06:53

+0

不将其称为C语言一部分的原因是因为您可以通过唱一个不同的库(使用相同的编译器)或编写自己的malloc/free代码来自定义行为。我曾经在98 - 99年左右这样做过。这会给您带来诸多好处,例如编写一个版本,可以在调试器中打印出所有已分配块的列表。 – 2011-03-24 03:37:08