我有一个动态数组,它包含一个包含'\n'字符的字符串,所以这个字符串由多行组成。我试图提取线条,并将它们全部放入2D字符数组中,但我遇到了分割错误。
这是我的代码:
char *input_lines = malloc(MAX_LINE_LEN*sizeof(char));
input_lines = extractInput(MAX_LINE_LEN, input_file);
char inputLines_counted[lineCount_input][MAX_LINE_LEN];
char *t = strtok(input_lines, "n");
for(i = 0; i < lineCount_input; i++) {
strcpy(inputLines_counted[i], t);
// printf("%sn", inputLines_counted[i]);
t = strtok(NULL, "n");
}
创建动态数组后,我使用extractInput(MAX_LINE_LEN, input_file)
函数用包含多行的字符串填充input_lines
数组。
以下是提取功能:
char *extractInput(int len, FILE *file) {
char tmp[len];
char *pos;
char *input_lines = malloc(len*sizeof(char));
char *lines;
while(fgets(tmp, len, file)) {
// if((pos = strchr(tmp, 'n')) != NULL) {
// *pos = ' ';
// }
input_lines = realloc(input_lines, (strlen(input_lines) + len)*sizeof(char));
strcat(input_lines, tmp);
}
return input_lines;
}
为什么我在这里会出现segfault?
函数调用
input_lines = realloc(input_lines, (strlen(input_lines) + len)*sizeof(char));
获取当前分配的内存块并展开它(如果可以的话(。您应该检查realloc的返回值,它可能会失败。
顺便说一句,当你在C中分配内存时,你总是需要为结尾\0留出空间。
看看这个文件会发生什么
hellon
worldn
第一个fgets在hello中读取到tmp中。
现在进行realloc,尽管这是不必要的,input_lines已经指向一个可以容纳字符串的缓冲区
char *input_lines = malloc(MAX_LINE_LEN*sizeof(char));
现在使用您的realloc
input_lines = realloc(input_lines, (strlen(input_lines) + len)*sizeof(char));
您执行strlen(input_lines(+len,因此使缓冲区strlen"hello\n"+len变长。
但你需要注意的重要一点是下面的
strcat(input_lines, tmp);
您还没有初始化inputline所指向的内存,它可以包含任何内容,甚至\0,所以您的strcat可能会将字符串放在缓冲区中的任何位置,并导致您描述的错误。
分配缓冲区时,请执行memset或使用calloc。
如果你使用realloc,你应该跟踪你已经分配的总大小以及你使用了多少,然后再复制到缓冲区,检查是否有足够的空间。如果没有,请向缓冲区添加一定数量的字节。
我还注意到,您逐行读取文件,然后将这些行连接在一起,以便稍后使用strtok再次分割它们。返回一组行会更有效率。