假设我有多个指向堆内存块的指针。假设第一个指针是内存的所有者,并且有几个额外的指针在我的应用程序中充当句柄。只要拥有者是唯一一个free
'd,我们没有内存泄漏,我们也不会释放一块内存。
/* Here is the owner */
size_t block_size = SOME_BLOCK_SIZE;
char *owner = malloc(block_size);
/* And a few handles that access the block in different places */
char *handle_1 = owner[10];
char *handle_2 = owner[359];
char *handle_3 = owner[172];
到现在为止还挺好。后来我们realloc
所有者增加容量
char *tmp = realloc(owner, 2 * SOME_BLOCK_SIZE);
if (!tmp) {
fprintf(stderr, "Error: could not reallocate array\n");
exit(-1);
}
if (tmp == owner) {
printf("We all know what happens here...\n");
printf("the owner array just increased size\n");
}
else {
printf("We had to move the owner array to a new memory address\n");
printf("What happens to the handles?\n");
}
有三种可能的结果:
realloc
失败,因为没有更多的记忆。realloc
成功地扩展了阵列而无需移动它。realloc
成功扩展了数组,但它已移至新的内存区域。我的问题是,在案例3中,我们之前定义的句柄会发生什么?我希望因为它们只是指针变量而且因为realloc
函数不知道它们的存在,所以句柄仍然指向旧的内存地址。很容易想象事情变得糟糕。
我的直觉是否正确?如果是这样,最好的方法是什么(除了从不调整大小)?我担心我只需要保留一个活动句柄列表,并在检测到owner
被移动时更新它们。我对如何实现这一点有一个想法,但我宁愿使用别人的聪明解决方案而不是重新发明轮子。
是的,就像ryan和true推荐的那样,你应该使用一个基指针(所有者)。在realloc的情况下,可以更新该基指针。您的句柄应作为此基指针的偏移量进行管理。
int handle1_off = 10;
int handle2_off = 359;
...
如果要访问句柄,则必须计算实际指针。
memcpy(owner + handle1_off, some_other_pointer, some_size);