void指针数组操作实现正确性咨询:元素获取与销毁
关于void指针数组容器的函数实现验证问题
用户定义了如下动态数组结构体:
typedef struct vector { void **array; size_t size; }vector;
随后实现了两个元素访问函数与一个销毁函数,希望验证实现的正确性:
- 用于获取指定位置元素引用的函数:
void **get_at(vector *this, size_t pos) { assert(pos >=0 && pos < this->size); return &this->array[pos]; }
- 用于获取指定位置元素指针的函数:
void *at(vector *this, size_t pos) { assert(pos >=0 && pos < this->size); return this->array[pos]; }
- 用于销毁数组的函数:
void destroy(vector *this) { free(this->array); free(this); }
一、元素访问函数的正确性验证
at函数完全正确:它直接返回容器中存储的第pos个void*指针,完全符合“获取指定位置元素指针”的需求。get_at函数实现正确,但需注意使用场景:它返回的是容器内部存储该void*指针的地址(void**类型),这确实是“元素的引用”——通过这个指针可以修改容器中存储的void*值(比如替换为其他指针)。但要注意,该返回值指向容器内部内存,若容器底层数组发生扩容重分配,这个地址会失效,不能长期持有。
额外补充:size_t是无符号类型,pos >= 0的判断完全多余(无符号数永远不会小于0),编译器大概率会优化掉这个判断,可直接写成assert(pos < this->size)。
二、销毁函数的合理性分析
destroy函数是否足够,核心取决于容器中void*指针指向的内存归属:
- 如果容器仅负责存储指针,元素内存由外部代码管理(比如用户自行分配/释放元素内存),那么当前
destroy函数就足够——只需释放容器自身的底层数组array和结构体this的内存即可。 - 如果容器设计为负责管理元素内存(比如插入函数会为元素分配内存),则必须遍历数组,逐个调用
free释放每个array[pos]指向的内存,之后再释放array和this,否则会造成内存泄漏。
举两个典型场景:
- 外部管理元素内存的使用场景:
vector* v = create_vector(); int* num = malloc(sizeof(int)); *num = 10; push_back(v, num); // 仅将num指针存入容器 // 调用destroy(v)后,需自行free(num),否则内存泄漏
这种情况无需在destroy中遍历释放元素。
- 容器管理元素内存的实现场景:
void push_back(vector* v, int value) { int* num = malloc(sizeof(int)); *num = value; v->array[v->size++] = num; }
此时destroy必须遍历释放每个array[pos],否则这些num的内存会永久泄漏。
内容的提问来源于stack exchange,提问作者Calvince
相关产品推荐
相关产品推荐

