我有一个类似数组的结构,使用单链表。如果我想删除某个单元格,是否必须释放指向它的指针(按行和按列)?
我的结构如下:
S -> C0 -> C1 -> C2 -> ...
v v v
R0 -> 00 -> 01 -> 02 -> ...
v v v
R1 -> 10 -> 11 -> 12 -> ...
v v v
R2 -> 20 -> 21 -> 22 -> ...
然后说我想删除11并重新链接。我必须使用01 AND 10中的指针释放11吗?
S -> C0 -> C1 -> C2 -> ...
v v v
R0 -> 00 -> 01 -> 02 -> ...
v v v
R1 -> 10 ->->v->->12 -> ...
v v v
R2 -> 20 -> 21 -> 22 -> ...
不,你没有"释放指针",你释放了指针指向的内存。
如果你再仔细想想,这应该很容易理解。考虑一下这样的代码,这意味着你要问的问题的简化视图:
void *ptr = malloc(1024); /* Allocate 1024 KB of memory, somewhere. */
void *copy1 = ptr;
void *copy2 = ptr;
void *copy3 = ptr;
void *copy4 = ptr;
当上面的程序运行后,假设分配成功,我们显然有五个指针指向相同的内存块。我们可以使用五个指针中的任何一个来取消内存分配,因为它们的值相同:
free(ptr3); /* Any one would work. */
当然,我们不能用多个指针调用free()
,因为所有指针都指向同一块内存。
您只能释放一次内存块,对同一地址多次调用free()
是未定义的行为(当然,除非您在两者之间进行了新的分配)。
这当然在你真正应该学习的手册页面中有解释:
free()
函数释放ptr所指向的内存空间,该内存空间必须由先前对malloc()
、calloc()
或realloc()
的调用返回。否则,或者如果以前已经调用过free(ptr)
,则会发生未定义的行为。如果ptr
是NULL
,则不执行任何操作。
否,事实上,不能两次释放同一对象。如果你有两个指针指向某个东西,一种方法是使用"共享指针"进行引用计数;另一种方法是在数据结构中使用原始指针,并在其他地方管理对象的生存期。或者,在您的特定情况下,您可以有一些约定,例如"上面"的指针是所有者,而"左边"的指针不是。
查找"double-free",你会发现如果你释放了两个指针,会出现什么样的错误。
顺便说一句,如果你释放了一个null指针,什么都不会做,所以处理这种事情的一种方法是在释放指针后总是将它们设置为null。在您的情况下,这意味着将两个指针设置为null,当然,以避免双重空闲的可能性。