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

C语言自定义vector扩容后外部指针指向异常问题排查求助

问题根因

C语言默认是值传递,你当前的insert函数的形参vector_t* v是外部实参指针的拷贝,函数内部修改v = cv的操作只会修改这个局部拷贝的指向,完全不会影响外部原来的vector指针。这就导致你在扩容逻辑里free(v)之后,外部的实参指针直接变成了野指针,下次调用insert时传入的就是已经被释放的内存地址,才会出现乱码的容量、大小值。

修复方案

有两种可行的修复方案:

方案1:仅扩容数据区(更推荐)

vector的结构体本身仅存储元数据,不需要随扩容重新分配,只需要重新分配p_data指向的数组即可,从根源避免指针指向修改的问题,同时性能更高,也符合动态数组的常规实现逻辑。
修改后的insert代码如下:

void insert(vector_t* v, int val){
    if(v == NULL){
        printf("ERROR: vector == NULL");
        return;
    }

    printf("BCapacity: %d\n", v->capacity);
    printf("BSize: %d\n", v->size);

    if(v->size >= v->capacity){
        // 仅扩容数据数组,不改动vector结构体本身
        int new_cap = v->capacity * 2;
        int* new_pdata = (int*)realloc(v->p_data, sizeof(int) * new_cap);
        if(new_pdata == NULL){
            printf("ERROR: realloc failed\n");
            abort();
        }
        v->p_data = new_pdata;
        v->capacity = new_cap;

        printf("INCapacity: %d\n", v->capacity);
        printf("INSize: %d\n", v->size);
    }

    v->p_data[v->size] = val;
    v->size++;

    printf("Capacity: %d\n", v->capacity);
    printf("Size: %d\n", v->size);
}

该方案不需要修改原有外部调用逻辑。

方案2:使用二级指针修改外部实参

如果你确实需要重新分配整个vector结构体,就需要传入二级指针,让函数可以修改外部实参的指向:
修改后的insert代码如下:

// 形参改为二级指针
void insert(vector_t** v, int val){
    if(v == NULL || *v == NULL){
        printf("ERROR: invalid vector pointer\n");
        return;
    }
    vector_t* real_v = *v;

    printf("BCapacity: %d\n", real_v->capacity);
    printf("BSize: %d\n", real_v->size);

    if(real_v->size >= real_v->capacity){
        vector_t* cv = createVector(real_v->capacity * 2);
    
        for(int i = 0; i < real_v->capacity; i++){
            cv->p_data[i] = real_v->p_data[i];
        }
        
        cv->size = real_v->size;

        free(real_v->p_data);
        free(real_v);
        // 修改外部实参的指向
        *v = cv;

        printf("INCapacity: %d\n", (*v)->capacity);
        printf("INSize: %d\n", (*v)->size);
    }

    (*v)->p_data[(*v)->size] = val;
    (*v)->size++;

    printf("Capacity: %d\n", (*v)->capacity);
    printf("Size: %d\n", (*v)->size);
}

对应的调用方式也需要同步修改,传入指针的地址:

// 原调用方式 insert(v, 数值); 改为:
insert(&v, 123);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 03:42:01