C语言栈实现中结构体嵌套联合体成员赋值不更新问题
问题原因
你代码中存在两个核心错误,直接对应你遇到的问题:
- 可变参数读取逻辑错误:
va_arg每调用一次就会将可变参数指针向后移动对应数据的长度,你在printf打印时已经调用了一次va_arg读取参数值,赋值时又调用了一次,第二次读取的是参数列表外的未知内存,自然得到垃圾值。 - 栈元素内存申请大小错误:
stack_malloc函数申请elements数组时,你使用了sizeof(stack->elements),而stack->elements是Stack_Element*类型的指针,sizeof取到的是指针本身的大小(32位系统为4字节、64位系统为8字节),远小于Stack_Element结构体的实际大小,会导致后续内存访问越界,也可能引发数据异常甚至程序崩溃。
修复方案
1. 修正可变参数读取逻辑
每个类型分支里只调用一次va_arg,把值存到临时变量后再分别用于打印和赋值即可。
2. 修正内存申请大小
将stack_malloc里的内存申请参数改为sizeof(Stack_Element) * capacity。
修正后完整代码
Stack* stack_malloc(unsigned capacity) { Stack* stack = (Stack*)malloc(sizeof(Stack)); stack->top = 0; stack->capacity = capacity; // 修正sizeof参数为Stack_Element类型大小 stack->elements = (Stack_Element*)malloc(sizeof(Stack_Element) * capacity); return stack; } void stack_push(Stack* stack, enum ELEMENT_TYPE type, ...) { if (isFull(stack)) { return; } va_list ap; va_start(ap, type); switch(type) { case ELEMENT_CHAR: { char val = (char) va_arg(ap, int); printf("Pushing char: %c\n", val); stack->elements[stack->top].val_c = val; printf("After pushing: %c\n", stack->elements[stack->top].val_c); break; } case ELEMENT_INT: { int val = va_arg(ap, int); printf("Pushing int: %d\n", val); stack->elements[stack->top].val_i = val; printf("After pushing: %d\n", stack->elements[stack->top].val_i); break; } case ELEMENT_DOUBLE: { double val = va_arg(ap, double); printf("Pushing double: %f\n", val); stack->elements[stack->top].val_d = val; printf("After pushing: %f\n", stack->elements[stack->top].val_d); break; } case ELEMENT_FLOAT: { float val = (float) va_arg(ap, double); printf("Pushing float: %f\n", val); stack->elements[stack->top].val_f = val; printf("After pushing: %f\n", stack->elements[stack->top].val_f); break; } } stack->elements[stack->top].type = type; stack->top++; va_end(ap); }
内容的提问来源于stack exchange,提问作者Sami
相关产品推荐
相关产品推荐

