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

函数内动态分配结构体数组:scanf仅首个元素有效问题求助

问题排查:动态分配结构体数组后的scanf读取异常

这个问题的核心是对二级指针的访问方式错误,导致除第一个元素外,后续的scanf都在错误的内存地址上操作,自然没法正确读取数据。咱们来拆解一下问题所在:

错误原因分析

在fc函数里,data是str**类型(指向指针的指针)。当你写data[i]->x时,C语言会把它解析为*(data + i)->x——也就是说,你把data当成了一个指针数组来访问,但实际上data只是一个指向str*的单个指针,根本不是数组。只有当i=0时,data[0]等价于*data(也就是你malloc出来的结构体数组首地址),所以第一个元素能正常读取;i>=1时,你就越界访问了完全无关的内存区域,读取自然失效。

两种修正方案

方案1:用临时变量存储数组首地址(推荐,代码更清晰)

先把二级指针解引用,拿到malloc出来的结构体数组的首地址,存在临时变量里,之后直接用下标访问数组元素:

void fc(str **data, int length){
    *data = malloc(length*sizeof(str));
    // 先拿到结构体数组的首指针
    str *arr = *data;
    for(int i=0; i<length;i++){
        scanf("%d", &arr[i].x);
    }
}

方案2:直接通过二级指针解引用后访问

如果不想用临时变量,也可以直接对二级指针解引用后使用下标,或者用指针偏移的方式:

void fc(str **data, int length){
    *data = malloc(length*sizeof(str));
    for(int i=0; i<length;i++){
        // 方式1:(*data)[i] 是数组的第i个元素,取它的x的地址
        scanf("%d", &(*data)[i].x);
        // 方式2:等价于指针偏移后访问成员,效果和上面一样
        // scanf("%d", &((*data) + i)->x);
    }
}

完整健壮版代码

另外,别忘了加上内存分配失败的判断,以及使用完内存后的释放操作,避免内存泄漏:

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

typedef struct{ int x; }str;
void fc(str **data, int length){
    *data = malloc(length*sizeof(str));
    // 检查malloc是否成功
    if(*data == NULL){
        perror("malloc failed");
        exit(EXIT_FAILURE);
    }
    str *arr = *data;
    for(int i=0; i<length;i++){
        scanf("%d", &arr[i].x);
    }
}
int main(){
    str *data;
    int length=5;
    fc(&data, length);
    // 打印时加个空格,输出更易读
    for(int i=0; i<length;i++){
        printf("%d ", data[i].x);
    }
    // 释放动态分配的内存
    free(data);
    return 0;
}

内容的提问来源于stack exchange,提问作者O. Vitek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:10:48