realloc 移动内存块时如何更新其他指针?

Posted

技术标签:

【中文标题】realloc 移动内存块时如何更新其他指针?【英文标题】:How to update other pointers when realloc moves the memory block? 【发布时间】:2011-01-11 10:37:36 【问题描述】:

realloc 参考说:

该函数可能会移动内存块 到一个新的位置,在这种情况下 返回新位置。

是否意味着如果我这样做:

void foo() 

        void* ptr = malloc( 1024 );

        unsigned char* cptr = ( unsigned char* )ptr+256;

        ptr = realloc( ptr, 4096 );

如果 realloc 移动了块,那么 cptr 可能会失效?

如果是,那么 realloc 是否会以任何方式发出信号,表明它将移动块,以便我可以做一些事情来防止 cptr 变得无效?

【问题讨论】:

这是我提出的一个很好的问题 +1,因为它强调了涉及 realloc 的基本学习曲线...... 【参考方案1】:

是的,cptr 将随着 realloc 移动块而失效!不,没有提到向您发出信号告诉您它正在移动内存块。顺便说一句,您的代码看起来很可疑...请继续阅读...请参阅我的 answer 到另一个问题,并非常仔细地阅读代码以了解它如何使用 realloc。一般的共识是,如果你这样做:

无效 *ptr = malloc(1024); /* 稍后在代码中 */ ptr = realloc(ptr, 4096); /* 砰!如果 realloc 失败了,你的宝贵内存就被塞满了! */

解决这个问题的方法是使用临时指针并使用它,如下所示:

无效 *ptr = malloc(1024); /* 稍后在代码中 */ 无效 *tmp = realloc(ptr, 4096); 如果 (tmp != null) ptr = tmp;

编辑:感谢 Secure 指出我之前输入此内容时出现的一个 gremlin。

【讨论】:

这不是真正的代码——它只是展示我要做什么的东西。那么有没有办法在不移动现有内存块的情况下调整它的大小(或者告诉程序这是不可能的?)。如果我调用 realloc 并通过移动块成功,那么是否有可能以某种方式保持旧地址有效,以便我可以“撤消” realloc? 不!你不能这样做......那是编译器/链接器/运行时相关的。不,你不能保留旧地址,因为堆会在程序的过程和生命周期中变得碎片化。简而言之,您不能绝对确定旧地址,因为指针的本质是基于动态寻址...不,您无法撤消重新分配... 这是我见过的最无用的 malloc 返回值转换。还有为什么你投的是malloc的return,而不是realloc的return? @Secure:对此感到抱歉 - 那是古老的 skool C 编程......并且深深地烙印在我的脑海里......曾经在 90 年代初使用过 C 89 标准,那么你就会知道我的意思了米谈! :) @Secure:旧的 malloc 返回 void * 因此演员,我只是忘了把它放在 realloc 中..【参考方案2】:

是的,如果 realloc 移动了块,cptr 就会失效。

【讨论】:

对大喊大叫感到抱歉,但这有助于使简短的答案超过最小长度要求。【参考方案3】:

这有点晚了,但这个问题的解决方案(没有人提到过)是不使用指向需要分配的已分配块的指针。相反,使用基指针的整数值偏移量或(更好)使用struct 类型和成员元素来寻址分配对象中的特定位置。

【讨论】:

希望我能在写当前作业之前完成这些。我也认为这是 zajcev 的 OP 答案的一部分,解释了他能做些什么。【参考方案4】:

是的。

最好的办法是比较重新分配前后的ptr,看看它是否被移动了。您不应该分配指向偏移值的指针,而是应该存储偏移量,然后用它索引原始运算符。

而不是 void* newPtr = ptr + 10; *newPtr = something;

使用 int new = 10; ptr[new] = something;

【讨论】:

【参考方案5】:

是的,如果 realloc 移动块,cptr 将失效。

不,没有信号。您必须对照原始 ptr 位置检查返回值。

【讨论】:

以上是关于realloc 移动内存块时如何更新其他指针?的主要内容,如果未能解决你的问题,请参考以下文章

动态分配内存-realloc

零基础学C语言内存知识总结:realloc函数和free函数

realloc 会覆盖旧内容吗?

(void *) 的 realloc 中的内存泄漏以连接字符串

realloc ------ 扩大malloc得到的内存空间

realloc函数详解