二级指针应用
引子:在线性表 销毁函数中,传入二级指针作为参数,可以实现对线性表的销毁操作。
//销毁已存在的线性表
void DestroyList(list_t **L){
// Step 1: 检查L是否为非空指针
if(L)
// Step 2: 释放L指向的内存空间
free(*L);
// Step 3: 将L所指向的指针置为NULL,避免悬挂指针
*L=NULL;
}
上述代码主要功能是销毁一个已存在的线性表。通过接收一个二级指针(指向线性表的指针),函数首先检查传入的二级指针是否为非空。然后释放线性表所占用的内存空间,并将一级指针置为 NULL,从而避免悬挂指针的问题。这是对动态内存管理中销毁操作的安全处理方式。
list_t **L 为什么使用二级指针
在这个函数中,list_t **L 是一个二级指针,而不仅仅是一级指针,这是为了能够在函数内部修改指向线性表的指针。
原因:
1.直接操作并修改原指针: 如果传入的是一个一级指针 list_t *L,那么在函数内部只能操作其指向的内存内容,但无法修改这个指针本身。如果要让外部也能感知到这个指针已经被置为 NULL,需要使用二级指针。
2.避免悬挂指针: 如果只是释放内存而不置 NULL,外部仍然有一个一级指针指向已释放的内存,这会导致悬挂指针,进而可能引发崩溃或不可预知的错误。
例子对比
void DestroyList(list_t *L) {
if (L) free(L);
// 此处无法将传入的一级指针置为 NULL
}
void test() {
list_t *list = malloc(sizeof(list_t));
DestroyList(list);
// 此时 list 仍然指向原内存,但内存已经被释放,存在悬挂指针风险
}
通过使用二级指针,我们可以在函数内部将指针置为 NULL,避免悬挂指针:
void DestroyList(list_t **L) {
if (L && *L) {
free(*L);
*L = NULL;
}
}
void test() {
list_t *list = malloc(sizeof(list_t));
DestroyList(&list);
// 此时 list 已经被置为 NULL,避免悬挂指针
}
详细示例解释
void DestroyList(list_t **L) {
if (L && *L) {
// 释放 L 所指向的内存
free(*L);
// 将 L 所指向的第一个指针 (即原来的指针) 置为 NULL
*L = NULL;
}
}
void test() {
list_t *list = malloc