函数内动态分配结构体数组: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
相关产品推荐
相关产品推荐

