我正在尝试为指针创建一系列指针,至少要熟悉我的理解。但是我的阅读量是无效的,并在Valgrind运行中写作。
char **format_file(FILE *infile) {
char **char_array = malloc(20 * sizeof(char*));
int c;
int cUsed = 0;
while ((c = fgetc(infile)) != EOF) {
char_array[cUsed] = c;
cUsed += 1;
}
printf("%s", *char_array);
return char_array;
}
该代码通过从已经打开的文件" Infile"中读取来起作用。首先,我用malloc
分配了20个字符的内存,然后我试图通过字符读取文件字符到分配的内存数组中,直到达到EO
F。但是,Valgrind的输出如下:
==7379== Invalid read of size 1
==7379== at 0x4E7CB36: vfprintf (vfprintf.c:1597)
==7379== by 0x4E85198: printf (printf.c:35)
==7379== by 0x400755: format_file (formatter.c:27)
==7379== by 0x4006C1: main (format265alt.c:21)
==7379== Address 0x6f is not stack'd, malloc'd or (recently) free'd
第27行是Valgrind的printf
命令,它称为尺寸1的无效读数。
formatter.c是包含 format_file
函数的文件,而格式化265alt.c是一个调用formatter.c函数并打开要读取的文件的文件。
我对**的语法感到困惑,也就是说,如何访问和读/写分配的内存?
如果我没有提供有关此问题的足够信息,我深表歉意。
valgrind
抱怨,因为您在分配对象的末尾存储字符。编译器应抱怨您将字符存储到错误类型的对象中,使用-Wall -W
启用有用的警告。
char **
是指向炭指针的指针,它可以指向一系列的炭指针,也称为一系列字符串。您必须为文件内容分配数组和每个字符串。
这里有2种可能性:
-
该函数可以将整个文件加载到一个字符串中,但是无需将指针返回到
char*
,只需返回字符串(char *
)就足够了。 -
如果函数要返回一个指针转换为一系列字符串的指针,则每行,最后一个
NULL
在末尾,就像argv
数组将第二个参数传递给了该字符串,更合适main
功能。
为此,您必须重新分配字符串数组,因为从FILE*
读取更多行,并且随着其成长,每行应重新分配。在字符串数组的末尾添加NULL
指针以指示其末端。
这是一种非常低效的方法:
#include <stdlib.h>
#include <stdio.h>
char **format_file(FILE *infile) {
size_t lines = 0;
char **array = malloc(1 * sizeof(char*));
size_t pos = 0;
char *line = malloc(1);
int c;
while ((c = getc(infile)) != EOF) {
if (c == 'n') {
line[pos] = ' ';
array = realloc(array, (lines + 2) * sizeof(char *));
array[lines++] = line;
line = malloc(1);
pos = 0;
continue;
}
line = realloc(line, pos + 2);
line[pos++] = c;
}
if (pos > 0) {
line[pos] = ' ';
array = realloc(array, (lines + 2) * sizeof(char *));
array[lines++] = line;
} else {
free(line);
}
array[lines] = NULL;
return array;
}
如果您只是创建字符数组,则一维字符数组就足够了。无需char**
业务。但是,如果要将其用作字符串,请确保终止数组。