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

C语言多指针指向同一地址问题 结构体指针数组存CSV数据故障求解

问题根因

你遇到的两个问题核心都是错误引用了栈上临时内存的地址,具体如下:

  1. 所有数组元素指向同一个栈地址
  • 循环内部定义的data_t customer是栈局部变量,每次循环都会复用同一块栈内存,循环结束后这块内存会被系统回收。你先malloc了结构体堆内存,又直接把array[index]赋值为&customer,不仅造成了内存泄漏,还让所有数组元素都指向同一个栈地址,最终这个地址里保留的是最后一次循环写入的值,所以打印所有元素都和最后一个元素内容一致。
  1. name字段无法正常打印
  • strtok返回的是临时缓冲区buffer内部的指针,buffer同样是栈上的临时内存,每次循环都会被新读取的CSV行覆盖,循环结束后buffer内容失效,所以name字段指向的是无效内存,无法输出正确内容。
修复后完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct data data_t;
struct data
{
    char *name;
    int id;
    double balance;
};

int main(int argc, char **argv)
{
    FILE *fp = NULL;
    // 最多存10条数据,可根据需求调整
    data_t **array = (data_t **) malloc(10 * sizeof(data_t *));
    if (argc < 2)
    {
        printf("No file input\n");
        exit(1);
    }
    // 修复原代码运算符优先级错误,加括号保证先执行fopen赋值再判空
    if ((fp = fopen(argv[1], "r")) == NULL)
    {
        printf("File not found\n");
        exit(1);
    }
    char buffer[128];
    char delim[2] = ",";
    int index = 0;
    while(fgets(buffer, 128, fp) && index < 10) // 加边界判断避免数组越界
    {
        // 先解析当前行的所有字段
        char *name = strtok(buffer, delim);
        int id = atoi(strtok(NULL, delim));
        double balance = atof(strtok(NULL, delim));
        // 给当前结构体分配堆内存
        array[index] = (data_t *) malloc(sizeof(data_t));
        // 字符串单独分配内存复制内容,不要直接引用buffer的指针
        array[index]->name = strdup(name);
        array[index]->id = id;
        array[index]->balance = balance;
        index += 1;
    }
    fclose(fp);
    fp = NULL;

    // 测试打印代码
    for (int i = 0; i < index; i++) {
        printf("第%d条:name=%s, id=%d, balance=%.2f\n", i+1, array[i]->name, array[i]->id, array[i]->balance);
    }

    // 内存释放逻辑,避免泄漏
    for (int i = 0; i < index; i++) {
        free(array[i]->name);
        free(array[i]);
    }
    free(array);
    return 0;
}
核心修复要点
  • 不要把动态分配的结构体指针指向栈局部变量,直接把解析到的字段值赋值到堆内存的结构体成员中
  • 字符串类型的成员需要单独分配内存复制内容,可直接用strdup完成分配+复制的操作,如果环境不支持strdup可以替换为malloc(strlen(name)+1)加strcpy的实现
  • 补充了数组越界防护和原代码中fopen判断的运算符优先级错误,避免异常崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:36:01