使用单个循环使用文件数据分配和初始化缓冲区

问题描述 投票:0回答:2

我尝试使用低级文件描述符将文件读取到缓冲区。该方法假设将文件数据逐字节存储到

char *
缓冲区,解析该数据,然后释放分配的缓冲区。

static void
parse_file(char path[11]) {
  int fd = open(path, O_RDONLY);
  if (fd == -1) {
    fprintf(stderr, "Failed to open a file '%s'", path);
    exit(errno);
  }
  char c;
  char *buffer = {0};
  unsigned int i = 0;
  while (read(fd, &c, 1)) {
    buffer = malloc(sizeof(char));  // Why *buffer want work here?
    *buffer = c;
    ++buffer;
    ++i;
  }
  buffer = malloc(sizeof(char));
  *buffer = '\0';
  buffer = &buffer[0];
  printf("Buffer data:\n%s\n", buffer);

  // Parse buffer data
  // ...
  
  buffer = &buffer[0];
  for (unsigned int j = 0; j <= i; ++j) {
    free(buffer);
    ++buffer;
  }
}

我想出了上述解决方案,但 Flycheck 给了我一个

unix.Malloc
类型的警告:

Attempt to free released memory

如何在单个循环中逐个字符地分配缓冲区?

c buffer low-level-io
2个回答
1
投票

buffer = &buffer[0];
这样的构造是行不通的。循环(并设置)之后缓冲区指向最后一个字符(因此指向 )。获取第 0 个元素的地址只会给出最后一个元素的地址(作为缓冲区点)。您无法以这种方式“倒退”到第一个字符。 当您调用 then
free()
时,您开始释放最后一个元素,然后迭代之前未分配的某些内存区域。


-1
投票

上面的代码有三个问题值得一提:

  • *buffer = malloc(sizeof(char))
    不起作用,因为
    *buffer
    指的是
    char
    类型,而不是
    char *
    指针。

  • buffer = &buffer[0]
    不会将缓冲区重置到其初始位置。为此,您可以保存第一个元素的地址以供以后使用,也可以使用指针算术在循环中向后移动缓冲区。

  • 知道缓冲区大小后分配缓冲区会更有效。

我最终使用了一个具有固定大小的临时自动存储变量,并在读取循环后分配缓冲区的内存。

static void
parse_file(char path[11]) {
  int fd = open(path, O_RDONLY);
  if (fd == -1) {
    fprintf(stderr, "Failed to open a file '%s'\n", path);
    exit(errno);
  }
  const int MAX = 50;
  char c;
  char *buffer = {0};
  char tmp[MAX];
  unsigned int i = 0;
  while (read(fd, &c, 1)) {
    tmp[i] = c;
    ++i;
  }
  
  buffer = malloc(sizeof(char) * i + 1);
  tmp[i] = '\0';
  strcpy(buffer, tmp);
  printf("Buffer data:\n%s\n", buffer);

  // Parse buffer data
  // ...
  
  free(buffer);
}
© www.soinside.com 2019 - 2024. All rights reserved.