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

C语言单/双指针正确使用:Record数组读取后main中值乱码问题

问题分析与解决方案

核心问题1:指针传递方式错误

你当前的load_array函数接收的是Record*类型的指针参数,这是值传递——函数内部的array_of_records是外部指针的副本。当realloc需要重新分配内存时,新的内存地址只会赋值给函数内部的局部指针,而main函数里的原始指针array_of_records依然指向旧的内存地址(如果realloc释放了旧内存,这个指针就变成野指针),所以main里访问的是已经失效的内存,打印出垃圾值。

必须使用**指针的指针(双指针)**作为参数,让load_array能直接修改main中的指针变量。

核心问题2:字符串内存被提前释放

你在load_array里刚把malloc出来的string_field赋值给结构体成员,就立刻调用free(string_field),这会导致结构体的string_field变成悬空指针——指向的内存已经被释放,后续任何访问都是未定义行为,必须将这个free操作推迟到结构体不再使用的时候执行。


修改后的完整代码

结构体定义(不变)

typedef struct Record{
    int id; 
    char* string_field;
    int int_field;
    double double_field;
} Record;

main函数修改

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char const *argv[]){
    if(argc < 2){
        printf("Usage: ordered_array_main <file_name>\n");
        exit(EXIT_FAILURE);
    }
   
    int capacity = 2;
    Record* array_of_records = NULL;
    array_of_records = (Record*)malloc(capacity * sizeof(Record));

    // 传递指针的地址给load_array
    int size = load_array(argv[1], &array_of_records, capacity);

    // 打印第一个元素验证
    if(size > 0){
        printf("%d, %d\n", array_of_records[0].id, array_of_records[0].int_field); 
    }

    // 先逐个释放结构体中的字符串内存,再释放数组本身
    for(int i = 0; i < size; i++){
        free(array_of_records[i].string_field);
    }
    free(array_of_records);
    return 0;
}

load_array函数修改

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 参数改为Record**,接收指针的地址
int load_array(const char* file_name, Record** array_of_records, int capacity){
    int index_of_record = 0;
    FILE* fp = fopen(file_name, "r");
    if(fp == NULL){
        fprintf(stderr, "Failed to open file\n");
        exit(EXIT_FAILURE);
    }

    char buffer[1024];
    char* field[4];
    while(fgets(buffer, sizeof(buffer), fp)!=NULL){
        // 分割字符串(补全省略的strtok逻辑)
        field[0] = strtok(buffer, ",");
        field[1] = strtok(NULL, ",");
        field[2] = strtok(NULL, ",");
        field[3] = strtok(NULL, "\n");

        int id_field = atoi(field[0]);
        char *string_field = malloc((strlen(field[1])+1)* sizeof(char));
        strcpy(string_field, field[1]);
        int int_field = atoi(field[2]);
        double double_field = atof(field[3]);
        
        if(index_of_record >= capacity){
            Record* tmp = NULL;
            // 解引用双指针,获取原始指针的地址
            tmp = (Record*)realloc(*array_of_records, 2*capacity*sizeof(Record));
            if(tmp==NULL){
                fprintf(stderr, "Memory allocation failure\n");
                exit(EXIT_FAILURE);
            }
            // 更新原始指针的值
            *array_of_records = tmp;           
            capacity = 2*capacity;    
        }

        // 解引用双指针,操作数组元素
        (*array_of_records + index_of_record)->id = id_field;
        (*array_of_records + index_of_record)->string_field = string_field;
        (*array_of_records + index_of_record)->int_field = int_field;
        (*array_of_records + index_of_record)->double_field = double_field;

        printf("%d\n", (*array_of_records + index_of_record)->int_field);
        index_of_record++;

        // 移除这里的free(string_field)!
    }

    fclose(fp);
    return index_of_record;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:05:22