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); /* 稍后在代码中 */ 无效 *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 移动内存块时如何更新其他指针?的主要内容,如果未能解决你的问题,请参考以下文章
零基础学C语言内存知识总结:realloc函数和free函数
(void *) 的 realloc 中的内存泄漏以连接字符串