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

使用fread读取指针指向的多元素时出现段错误,原因是什么?

fread批量读取触发段错误的原因分析

首先看定义的结构体:

typedef struct {
    int nr_operations;
    int *operations_idxs;
} sensor;

尝试从文件读取operations_idxs指向的数组元素时,以下代码会出现段错误:

S[i].operations_idxs=(int*)malloc(S[i].nr_operations*sizeof(int));
fread(&S[i].operations_idxs, sizeof(int), S[i].operations_idxs, f);

而通过循环逐个读取的代码可以正常获取数据:

S[i].operations_idxs=(int*)malloc(S[i].nr_operations*sizeof(int));
for( j=0; j<S[i].nr_operations; j++) {
    fread(&S[i].operations_idxs[j], sizeof(int), 1, f);
}

错误根源在于fread的参数完全用错了:

  • 第一个参数错误:&S[i].operations_idxs是取指针变量自身的地址,而我们需要写入的是指针指向的malloc分配好的内存区域,应该直接传递S[i].operations_idxs(指针变量的值就是目标内存的起始地址)。如果传指针的地址,fread会把文件内容覆盖掉指针本身存储的malloc返回的有效地址,后续再通过这个指针访问内存时,就会指向非法地址,触发段错误。
  • 第三个参数错误:fread的第三个参数是要读取的元素个数,你传入的S[i].operations_idxs是一个指针,会被强制转换成整数(也就是malloc返回的内存地址,通常是一个很大的数值),fread会尝试读取这么多个int元素,远远超出了分配的内存大小和文件中的实际数据量,直接导致内存越界访问,触发段错误。正确的元素个数应该是S[i].nr_operations。

正确的批量fread写法:

S[i].operations_idxs = (int*)malloc(S[i].nr_operations * sizeof(int));
// 目标内存地址 | 单个元素大小 | 元素个数 | 文件指针
fread(S[i].operations_idxs, sizeof(int), S[i].nr_operations, f);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:37:27