C语言宏实现数据入栈失效问题排查求助
问题分析与修正
核心错误1:PUSH调用缺失分号
你代码中PUSH(int_vec, 22)后面没有添加分号,这会导致语法错误,破坏代码的语法结构,编译器会直接报错,这也是你观察到PUSH操作失效的直接原因。
核心错误2:扩容逻辑的边界漏洞
当向量的active_length为0时,扩容分支中new_size = vec.active_length * 2会计算出0,调用realloc会将数组内存缩为0,后续无法正常添加元素。
次要问题
INIT_VECTOR宏中,malloc失败时执行free(ptr)是多余的:ptr此时为NULL,free(NULL)不会产生任何实际操作,可直接删除。- 宏中使用的
typeof是GCC扩展语法,代码不具备标准C兼容性,这是宏实现的固有局限性之一。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <stddef.h> #define VECTOR_STRUCT(type) \ struct {type *array; size_t allocated_length; size_t active_length; } #define INIT_VECTOR(vec, length) ({ \ size_t _a = (length); \ typeof(vec.array) ptr = malloc(_a * sizeof(*vec.array)); \ if (ptr == NULL) { \ fprintf(stderr, "malloc failed in file %s at line %d\n", __FILE__, __LINE__); \ exit(EXIT_FAILURE); \ } \ vec.allocated_length = _a; \ vec.active_length = 0; \ vec.array = ptr; \ }) #define PUSH(vec, data) ({ \ typeof(*vec.array) _a = (data); \ if (vec.active_length + 1 > vec.allocated_length) { \ size_t new_size = (vec.active_length == 0) ? 1 : vec.active_length * 2; \ typeof(vec.array) ptr = realloc(vec.array, new_size * sizeof(*vec.array)); \ if (ptr == NULL) { \ fprintf(stderr, "realloc failed in file %s at line %d\n", __FILE__, __LINE__); \ exit(EXIT_FAILURE); \ } \ vec.array = ptr; \ vec.allocated_length = new_size; \ } \ vec.array[vec.active_length] = _a; \ vec.active_length += 1; \ }) int main() { VECTOR_STRUCT(int) int_vec; INIT_VECTOR(int_vec, 30); // 修正:添加分号 PUSH(int_vec, 15); PUSH(int_vec, 22); printf("%d\n", int_vec.array[0]); printf("%d\n", int_vec.array[1]); int_vec.array[0] = 32; int_vec.array[1] = 22; // 修正:循环范围改为2,避免访问未初始化的索引 for (size_t i = 0; i < 2; i++) { printf("%d\n", int_vec.array[i]); } free(int_vec.array); return 0; }
关键修改说明
- 给第二个
PUSH调用添加分号,修复语法错误。 - 扩容时新增判断:当
active_length为0时,将新容量设为1,避免出现0大小的数组。 - 删除
INIT_VECTOR中多余的free(ptr)语句。 - 调整main函数中的循环范围,避免访问未初始化的数组元素。
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

