我尝试使用低级文件描述符将文件读取到缓冲区。该方法假设将文件数据逐字节存储到
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
如何在单个循环中逐个字符地分配缓冲区?
像
buffer = &buffer[0];
这样的构造是行不通的。循环(并设置)之后缓冲区指向最后一个字符(因此指向 )。获取第 0 个元素的地址只会给出最后一个元素的地址(作为缓冲区点)。您无法以这种方式“倒退”到第一个字符。
当您调用 then free()
时,您开始释放最后一个元素,然后迭代之前未分配的某些内存区域。
上面的代码有三个问题值得一提:
*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);
}