2010-01-31 89 views
17

的realloc的参考表示:如何在realloc移动内存块时更新其他指针?

功能可以存储块 移动到新的位置,在这种情况下,返回 新位置。

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

void foo() { 

     void* ptr = malloc(1024); 

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

     ptr = realloc(ptr, 4096); 
} 

然后CPTR可如果realloc的移动块状失效?

如果是的话,那么确实realloc的信号,以任何方式,它将移动块,这样我可以做些什么来防止CPTR成为无效?

+0

这是一个很好的问题+1,因为它强调了涉及realloc的基本学习曲线...... – t0mm13b 2010-01-31 15:45:28

回答

6

是,cptr将成为无效!不,没有提到你要告诉它正在移动内存块的信号。顺便说一下,你的代码看起来有点......请继续阅读...请参阅我的answer另一个问题,并仔细阅读代码,了解它如何使用realloc。普遍的共识是,如果你这样做:

 
void *ptr = malloc(1024); 

/* later on in the code */ 

ptr = realloc(ptr, 4096); 

/* BAM! if realloc failed, your precious memory is stuffed! */ 

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

 
void *ptr = malloc(1024); 

/* later on in the code */ 

void *tmp = realloc(ptr, 4096); 

if (tmp != null) ptr = tmp; 

编辑:感谢安全为指出一个gremlin,当我在前面输入这个内容时,这个gremlin在爬行。

+0

这不是真正的代码 - 它只是显示我要做的事情。那么是否有任何方法可以在不移动内存的情况下重新调整内存块的大小(或者告诉程序它不可能?)。如果我调用realloc并通过移动块成功,那么是否有可能以某种方式保持旧地址有效,以便我可以“撤消”realloc? – zajcev 2010-01-31 15:39:37

+0

不!你不能这么做......这是编译器/链接器/运行时依赖。不,你不能保留旧地址,因为在整个程序的整个过程和整个生命周期中,堆将会被分割。总之,你不能绝对固定旧地址,因为指针的本质是基于动态寻址......并且不能撤消重新分配...... – t0mm13b 2010-01-31 15:43:28

+0

这是malloc的返回值的最无用的转换,我见过。你为什么要投入malloc的返回,而不是realloc的返回? – Secure 2010-01-31 17:35:55

3

是。做

最好的事情是PTR前和重新分配后进行比较,看它是否已被移动。您不应该为偏移量值指定一个指针,而应该存储偏移量,然后使用它为原始运算符编制索引。

即代替 void* newPtr = ptr + 10; *newPtr = something;

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

2

是的,如果realloc的移动块的CPTR变为无效。如果realloc的移动块状

+0

抱歉的喊叫,但它有助于得到通过最小长度要求的简短答案。 – bmargulies 2010-01-31 15:07:29

4

是,cptr将失效。

没有,没有信号。您将不得不根据原始ptr位置检查返回值。作为realloc的移动块状

4

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

+0

希望我在写完我目前的任务之前完成了这一步。 我也认为这是zajcev的OP的答案的一部分,解释他可以做些什么。 – gone 2014-04-12 06:59:07