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

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;
}

关键修改说明

  1. 给第二个PUSH调用添加分号,修复语法错误。
  2. 扩容时新增判断:当active_length为0时,将新容量设为1,避免出现0大小的数组。
  3. 删除INIT_VECTOR中多余的free(ptr)语句。
  4. 调整main函数中的循环范围,避免访问未初始化的数组元素。

内容的提问来源于stack exchange,提问作者Jon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:06:22