C语言中指向重新分配内存块的多个指针
假设我有多个指向堆内存块的指针。假设第一个指针是内存的所有者,在整个应用程序中,还有几个额外的指针充当句柄。只要所有者是唯一可用的,我们就不会有内存泄漏,也不会双重释放内存块C语言中指向重新分配内存块的多个指针,c,pointers,memory-management,C,Pointers,Memory Management,假设我有多个指向堆内存块的指针。假设第一个指针是内存的所有者,在整个应用程序中,还有几个额外的指针充当句柄。只要所有者是唯一可用的,我们就不会有内存泄漏,也不会双重释放内存块 /* 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 */
/* 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
成功扩展了阵列,但它已移动到新的内存区域realloc
函数不知道它们的存在,所以句柄仍然指向旧的内存地址。很容易想象事情会变糟
我的直觉正确吗?如果是这样,最好的解决方法是什么(除了永远不调整大小)?恐怕我必须保留一个活动句柄的列表,并在检测到
所有者
已移动时更新它们。我对如何实现这一点有一个想法,但我宁愿使用其他人的聪明解决方案,也不愿拙劣地重新发明轮子。是的,像ryan和true推荐的那样,您应该使用基本指针(所有者)。在realloc的情况下,可以更新此基指针。您的句柄应作为对此基指针的偏移量进行管理
int handle1_off = 10;
int handle2_off = 359;
...
如果要访问句柄,必须计算实际指针
memcpy(owner + handle1_off, some_other_pointer, some_size);
是的,像ryan和true一样,您应该使用一个基指针(所有者)。在realloc的情况下,可以更新此基指针。您的句柄应作为对此基指针的偏移量进行管理
int handle1_off = 10;
int handle2_off = 359;
...
如果要访问句柄,必须计算实际指针
memcpy(owner + handle1_off, some_other_pointer, some_size);
是的,其他指针也需要在
realloc
之后更新。这里有很多选项–例如,将它们存储为偏移量而不是指针,因此您只需要更新一个基指针。存储偏移量是一个简单而聪明的想法。不幸的是,我需要指针地址,因为在我的应用程序中,指针地址被gsl\u matrix\u视图
(一种允许将数组视为二维矩阵的结构)使用。我认为我需要编写一个钩子来更新我的矩阵视图,当我检测到底层数组已经调整大小时。不要复制所有者的内容,而只传递/分发它的地址。作为一个编写大量多线程应用程序的人,这个总体设计是。。令人担忧。是的,其他指针也需要在realloc
之后更新。这里有很多选项–例如,将它们存储为偏移量而不是指针,因此您只需要更新一个基指针。存储偏移量是一个简单而聪明的想法。不幸的是,我需要指针地址,因为在我的应用程序中,指针地址被gsl\u matrix\u视图
(一种允许将数组视为二维矩阵的结构)使用。我认为我需要编写一个钩子来更新我的矩阵视图,当我检测到底层数组已经调整大小时。不要复制所有者的内容,而只传递/分发它的地址。作为一个编写大量多线程应用程序的人,这个总体设计是。。担心