You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 14:57:01