指针(和指针指针)相对容易理解,当你有简单的类型,如int,char等,但我总是发现当你有动态内存分配和指针(指针)时很难理解结构。
这就是为什么我发布了一个早期的线程试图理解为一个简单的结构动态分配内存的原因。我最近开始研究指针指针的使用,并试图在另一个线程中进行实际练习:Why use double pointer? or Why use pointers to pointers?特别是它所说的部分
"指针指针也派上用场,因为"处理"记忆在哪里 你想传递一个"手柄"功能之间重新定位 。存储器"
按照线程中提供的代码模板,我创建了以下函数(LIB_OBJECT是一个在线程模板中定义的简单结构):
void lib_free_memblock(LIB_OBJECT** memblock)
{
if (*memblock) {
free(*memblock);
*memblock = NULL;
}
}
LIB_OBJECT **lib_create_memblock(void)
{
LIB_OBJECT *memblock = (LIB_OBJECT*) malloc(10 *
sizeof(LIB_OBJECT));
LIB_OBJECT **ptr_to_memblock = (LIB_OBJECT **) malloc(sizeof(LIB_OBJECT*));
*ptr_to_memblock = memblock;
if (ptr_to_memblock == NULL)
{
printf("Memory block allocation (memblock) failed!\n");
exit(1);
}
printf("%d bytes of memory block successfully allocated starting at address %x\n", NUM_OBJECTS, *ptr_to_memblock);
return ptr_to_memblock;
}
void lib_resize_memblock (LIB_OBJECT **b, int new_size)
{
*b = (LIB_OBJECT*) realloc ((void *)*b, new_size);if (b == NULL)
{
printf("Resizing memory block failed!\n");
exit(1);
}
printf("Memory block at start address %x has been resized to %d bytes\n", *b, new_size);
}
该计划成功运作:
LIB_OBJECT **my_memblock = lib_create_memblock();
lib_resize_memblock(my_memblock, 20);
lib_free_memblock(my_memblock);
10 bytes of memory block successfully allocated starting at address 233c010
Memory block at start address 233c010 has been resized to 20 bytes
然而,当我改变
时*ptr_to_memblock = memblock;
到
ptr_to_memblock = &memblock;
我可以使用lib_create_memblock成功分配10个字节:
10 bytes of memory block successfully allocated starting at address 1c2b010
但程序崩溃在lib_resize_memblock:
Breakpoint 2, lib_resize_memblock (b=0x7fffffffdf40, new_size=20)
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa3c01 in realloc_hook_ini () from /lib64/libc.so.6
现在不是
*ptr_to_memblock = memblock;
和
ptr_to_memblock = &memblock;
相同?
有人可以澄清一下吗?
如果我理解正确,* b是分配的存储块的起始地址,** b是指向所分配的存储块的起始地址的指针,从而允许程序员对分配的存储块进行修改。然后,编译器如何理解lib_resize_memblock中的* b是什么意思,我们将** b作为函数的参数发送?从以下初始化?
*ptr_to_memblock = memblock;
我猜编译器遵循链式连接,从指针指针到指针,最后到指针所指向的地址,我所要做的就是建立正确的连接,对吗?提前谢谢..
答案 0 :(得分:1)
您的原始版本的代码有效(但有一些不必要的guff,因为我稍后会解释)。问题:
ptr_to_memblock = &memblock;
是memblock
是create函数的局部变量,它的生命周期在函数返回时结束。因此,该行最终将返回指向不再存在的变量的指针。
此外,这会泄漏您malloc
的内存,因为不再有任何内容指向该内存。
实际上,create函数有一个不必要的间接层,并且你的整个代码都有内存泄漏,因为你从来没有free
对应malloc
。使用以下内容会好得多:
LIB_OBJECT *lib_create_memblock(void) ;
只返回memblock
而根本不打扰ptr_to_memblock
。您的主要功能有几个选项,您可以自动分配"句柄":
LIB_OBJECT *my_memblock = lib_create_memblock();
lib_resize_memblock(&my_memblock, 20);
lib_free_memblock(&my_memblock);
或者你可以使用malloc来处理句柄(除非你有充分的理由,这是不必要的复杂):
LIB_OBJECT **pp_memblock = malloc(sizeof *pp_memblock);
*pp_memblock = lib_create_memblock();
lib_resize_memblock(pp_memblock, 20);
lib_free_memblock(pp_memblock);
free(pp_memblock);
答案 1 :(得分:0)
* ptr_to_memblock = memblock;在这种情况下,ptr_to_memblock =& memblock不相同。
当你看到
LIB_OBJECT ** ptr_to_memblock =(LIB_OBJECT **)malloc(sizeof(LIB_OBJECT *));
和
* ptr_to_memblock = memblock;
您正在创建一个指向指针的指针,该指针实际上包含任何日期的10个连续位置。第二个表达式暗示存储在ptr_to_memblock中的地址是该数据的地址。这也是memblock中的相同值。但这些方程式意味着有两件事指向数据。一个是memblock,另一个是指针,其地址在ptr_to_memblock中。因此有两个单独的指针。
现在考虑,ptr_to_memblock =& memblock: ptr_to_memblock存储memblock指针的地址。因此ptr_to_memblock指向memblock,而memblock又指向数据。因此,只有一个指向数据的指针。
希望这会有所帮助!!