嘿,我想要一些帮助,我想在我的c程序上加载字典,但我采取段故障。我会喜欢一些帮助。在使用gdb进行调试时,它说它在第63行失败了,命令说:lines[i]=string_coppied
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int step=200;
char **loadfile();
int main()
{
char **words=loadfile();
if (words==NULL) printf ("cant build structure");
for (int i=0 ; i<100 ; i++) printf("%s \n" , words[i] );
}
char **loadfile()
{
//We load our text file at the stack
FILE * fpointer;
fpointer = fopen ("word.txt" , "r");
if (fpointer==NULL) printf ("file not loaded \n");
else printf ("File loaded \n");
int array_size=step;
char ** lines=(char **)malloc(array_size*sizeof(char*));
if (lines=NULL) printf ("cant allocate memory \n");
char temp[100];
int i=0;
while (fgets(temp,100,fpointer))
{
//we check if the already allocated memory is full , if so we realloc
if (i==array_size)
{
array_size +=step;
char **newlines= (char**)realloc(lines , array_size * sizeof(char*));
if (newlines==NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return 0 ;
}
lines=newlines;
}
//now that we made sure that the memory was allocated we continue by copying the temp //
temp[strlen(temp)-1]="\0" ;
int length =strlen(temp);
char * string_coppied=malloc((length+1) * sizeof(char));
strcpy(string_coppied ,temp);
lines[i]=string_coppied;
i++;
}
return lines;
free(lines);
fclose(fpointer);
}
gdb说它在第63行失败,命令说:
lines[i]=string_coppied
这是因为之后
char **newlines= (char**)realloc(lines , array_size * sizeof(char*));
你不能在realloc之后使用行,因为如果可能被realloc释放,并且可见这是因为gdb发出了问题的信号
但是你的代码中存在更多问题
1)编译器在temp[strlen(temp)-1]="\0" ;
行上发出错误信号,因为temp是char数组,而不是char *数组,你当然想要temp[strlen(temp)-1] = 0 ;
2)主要:
if (words==NULL) printf ("cant build structure"); for (int i=0 ; i<100 ; i++) printf("%s \n" , words[i] );
缺少一个else,如果worlds为NULL,你可以执行for和(尝试)访问带有未定义行为的words[i]
3)在主要
for (int i=0 ; i<100 ; i++) printf("%s \n" , words[i] );
您可以访问100个第一个单词条目来打印它们而不知道它的大小/它有多少条目,如果它有少于100个条目你有另一个未定义的行为,如果有更多你没有打印所有这些条目
loadfile必须返回条目数,例如通过输出变量char **loadfile(size_t * n)
允许你做for (int i=0 ; i<n ; i++) ...
4)在loadfile中
fpointer = fopen ("word.txt" , "r"); if (fpointer==NULL) printf ("file not loaded \n"); else printf ("File loaded \n");
如果你无法打开文件文件,你打印一条消息,你继续执行,你需要return NULL;
请注意,您也很乐观,因为您在打开文件时已经打印了File loaded
5)在loadfile中
char ** lines=(char **)malloc(array_size*sizeof(char*)); if (lines=NULL) printf ("cant allocate memory \n");
如果malloc返回NULL,则打印消息并继续执行,因此当行为NULL且未定义的行为时,您可以稍后执行lines[i]=string_coppied;
6)在loadfile中
就像我说的
char **newlines= (char**)realloc(lines , array_size * sizeof(char*)); if (newlines==NULL) //check if the memory was allocated { printf ("Cant reallocate memory , please try again \n "); return 0 ; } lines=newlines;
可以替换为
lines= (char**)realloc(lines , array_size * sizeof(char*));
if (lines==NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return NULL;
}
7)在loadfile中
在做什么时(我将“\ 0”更改为0):
temp[strlen(temp)-1]=0; int length =strlen(temp);
当你知道第二个strlen值第一个减去1时,你计算字符串长度的2倍
int length = strlen(temp) - 1;
temp[length] = 0;
但还有一个问题,你这样做是为了删除换行符,但是
要不切割线条,也不必复制它们,可以使用getline
8)在loadfile中
在
return lines; free(lines); fclose(fpointer);
最后两行无法执行,所以你没有自由行(但这更好,因为你返回它)并且文件没有关闭
一份提案 :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int step=200;
char **loadfile(ssize_t * n);
int main()
{
ssize_t n;
char **words=loadfile(&n);
if (words == NULL)
puts("error when reading file");
else {
for (ssize_t i = 0 ; i < n ; i++) {
puts(words[i]);
free(words[i]);
}
}
}
char **loadfile(ssize_t * n)
{
*n = 0;
//We load our text file at the stack
FILE * fpointer = fopen ("word.txt" , "r");
if (fpointer==NULL) {
printf ("file not loaded \n");
return NULL;
}
puts ("load file");
int array_size = 0;
char ** lines = NULL;
for (;;) {
char * lineptr = NULL;
size_t zero = 0;
ssize_t sz = getline(&lineptr, &zero, fpointer);
if (sz <= 0) {
fclose(fpointer);
return lines;
}
if (lineptr[sz - 1] == '\n')
lineptr[sz - 1] = 0;
if (*n == array_size)
{
array_size += step;
lines = realloc(lines , array_size * sizeof(char*));
if (lines == NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return NULL;
}
}
lines[*n] = lineptr;
*n += 1;
}
}