【发布时间】:2015-02-03 02:24:56
【问题描述】:
当你有简单的类型,如 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 是指向分配的内存块的起始地址的指针,因此允许程序员对分配的内存块进行修改。那么,编译器如何理解 *b 在 lib_resize_memblock 中的含义,我们将 **b 作为参数发送给函数?从下面的初始化?
*ptr_to_memblock = memblock;
我猜编译器遵循链式连接,从指针到指针再到指针,最后到指针指向的地址,我所要做的就是建立正确的连接,对吗?提前谢谢..
【问题讨论】:
-
在
alloc调用周围和内部有一堆不必要的转换;将它们全部删除。此外,create函数生成了 10 个 objects,但 resize 函数生成了 bytes 的数量,这是一个不一致的接口;我建议更改 resize 函数以将对象的数量作为参数 -
我记得读过一篇文章说强制转换 malloc 是不必要的,我想这就是您的意思(“内部”,我不明白您所说的“周围”到底是什么意思)。关于 bytes 参数,我错过了 - 我实际上在头文件中定义了 NUMBER_OF_OBJECTS,我将在函数中更正它..
-
这就是我所说的“环绕”; “内部”是
realloc ((void *)*b -
现在知道了,再次感谢!
-
在您放弃内存块管理之前,我强烈建议您检查使用或不使用指针到指针逻辑的不同算法如何工作,并且可以使用 。最简单的方法之一是在插入新节点时保持顺序的单链表。算法基本相同,因为必须找到插入的“位置”。然而,实现有很大不同(您会惊讶于指针到指针的方法有多短)。挑战自己并尝试编写代码。
标签: c pointers dynamic-memory-allocation