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

使用readv读取文件时为iovec数组赋值基地址出现段错误排查

问题根因分析
  • 缓冲区分配不足:你定义的buffers是指向长度为1001的char数组的指针,仅通过malloc分配了2个该类型数组的空间,循环却要访问buffers[0]到buffers[999],属于严重的堆内存越界访问,这是触发段错误的核心原因。
  • strlen使用错误:malloc申请的内存默认未初始化,存储的都是随机垃圾值,strlen(buffers[i])会尝试在垃圾内存中查找\0结束符,大概率触发内存越界。另外iov_len的作用是告知readv当前缓冲区可接收的最大字节数,不需要通过strlen计算,直接设置为缓冲区可用长度即可。
  • 指针取值逻辑错误:buffers[i]本身就指向第i个1001字节数组的首地址,不需要额外加&取地址,多余的取地址操作不会改变地址值,但会导致类型逻辑错误,进一步加剧越界风险。
  • 输出逻辑存在隐患:readv读取到的内容是原始二进制字节,不会自动追加\0结束符,直接用printf("%s")输出会导致字符串读取越界。
  • 缺少错误检查:你没有判断open、malloc的返回值,若文件打开失败、内存申请失败也会触发异常。
修正后的完整代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <string.h>
#include <sys/stat.h>

#define IP_FORMAT "*.*.*.*/*,*,*,*,*,*,*,*"
#define BUF_COUNT 1000   // 缓冲区数量
#define BUF_SIZE 1001    // 单个缓冲区大小

int main()
{
  // 申请BUF_COUNT个大小为BUF_SIZE的缓冲区
  char (*buffers)[BUF_SIZE] = malloc(sizeof(char[BUF_COUNT][BUF_SIZE]));
  if (buffers == NULL) {
    perror("malloc failed");
    return 1;
  }

  struct iovec iov[BUF_COUNT];
  int fd = open("./geoip2-ipv4_csv.csv", O_RDONLY);
  if (fd == -1) {
    perror("open file failed");
    free(buffers);
    return 1;
  }

  // 初始化iovec结构体
  for (int i = 0; i < BUF_COUNT; i++) {
    iov[i].iov_base = buffers[i];
    iov[i].iov_len = BUF_SIZE - 1; // 留1字节存结束符
  }

  int valread = readv(fd, iov, BUF_COUNT);
  if (valread == -1) {
    perror("readv failed");
    close(fd);
    free(buffers);
    return 1;
  }

  // 输出读取到的内容
  for(int i = 0; i < BUF_COUNT; i++) {
    buffers[i][BUF_SIZE - 1] = '\0'; // 手动添加字符串结束符
    printf("%d: %s", i, buffers[i]);
  }

  // 资源释放
  close(fd);
  free(buffers);
  return 0;
}
补充注意点
  • 如果不需要1000个这么多的缓冲区,可以根据实际需求调整BUF_COUNT宏的取值,避免不必要的内存浪费。
  • readv会按顺序填充iovec数组里的缓冲区,返回值是读取到的总字节数,你可以根据返回值按需处理读取到的内容,不需要强制遍历所有缓冲区。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:54:08