C语言动态数组追加元素时使用二级指针的原因疑问
为什么动态数组追加元素需要传二级指针?
相关示例代码如下:
#include "append.h" int append(int ** tab, size_t *size, int value){ int *nouveauTab = realloc(*tab, (*size + 1) * sizeof(int)); if (nouveauTab == NULL){ return 0; } *tab = nouveauTab; (*tab)[*size] = value; (*size)++; return 1; }
核心原因:C语言参数默认是值传递
你可以把指针也理解成普通变量,它本身也占用内存空间,存储的是其他数据的内存地址。
- 如果你给
append传一级指针int* tab,函数拿到的是外部指针的副本,你在函数内部修改这个副本的指向(比如把realloc返回的新地址赋值给它),改动只会作用在函数内部的临时变量上,外部的原指针完全感知不到,最后要么出现野指针,要么扩容后的地址直接丢失造成内存泄漏。 - 传二级指针
int** tab的时候,你传的是外部指针变量本身的内存地址,函数内部通过*tab解引用,就能直接修改外部原指针变量存储的地址值,这样realloc返回的新地址才能正确同步到函数外部。
示例代码逐行说明
int ** tab参数:接收外部动态数组指针的地址realloc(*tab, (*size + 1) * sizeof(int)):先解引用tab拿到外部原指针指向的堆内存地址,传入realloc做扩容*tab = nouveauTab:扩容成功后把新的堆内存地址赋值给外部原指针,确保外部可以访问到扩容后的数组- 后续操作就是在新数组的末尾插入元素、更新数组长度即可。
更易读的替代写法
如果觉得二级指针不好理解,也可以把动态数组封装成结构体,传结构体指针即可,本质逻辑完全一致:
typedef struct { int *data; size_t size; } IntArray; int append(IntArray *arr, int value) { int *new_data = realloc(arr->data, (arr->size + 1) * sizeof(int)); if (!new_data) return 0; arr->data = new_data; arr->data[arr->size] = value; arr->size++; return 1; }
内容的提问来源于stack exchange,提问作者Mohamed Faid
相关产品推荐
相关产品推荐

