【发布时间】:2018-07-04 00:07:19
【问题描述】:
我是编码新手,所以我知道我可能会搞砸一些事情。我想创建一个 (number_of_text_words)x(number_of_letters_of each_word) 维度的数组,我将在其中逐个字符地保存单词并将 '\0' 放在最后,以便被识别为字符串。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main(int argc, char **argv)
{
FILE *myinput;
int i,k,sum,words_num,j;
char **dict=NULL;
char *num_words=NULL;
myinput = fopen("bug.txt","r");
if (myinput == NULL)
{
fprintf(stderr, "ERROR:\n");
return;
}
fseek(myinput,0,SEEK_END);
int size = ftell(myinput);
fseek(myinput,0,SEEK_SET);
char *data = malloc(size);
if (data==NULL)
return -1;
fread(data,size,1,myinput);
fclose(myinput);
sum=0;
for (i=0;i<=size-1;i++)
if (data[i]=='\n')
sum++;//count the words by the spaces
/*for (i=0;i<=size-1;i++)
printf("%c\n",data[i]);*/
/*printf("\n%d\n",sum);*/
dict=malloc(sum);//for saving the words
if (dict==NULL)
return -1;
num_words=malloc(sum);//for saving the number of letters of each word
if (num_words==NULL)
return -1;
j=0;
for (i=0;i<sum;i++){
words_num=0;
while ((data[j++]!='\n'))
words_num++;//allocate the exact needed memory for each word
dict[i]=malloc(words_num+1);//FOR THE FINAL '\0'
if (dict[i]==NULL)
return -1;
num_words[i]=words_num;
}
k=0;
for (i=0;i<sum;i++){
for(j=0;j<num_words[i];j++){
if ((data[k]=='\n') || (data[k]==EOF))
k++;
if (k<size)
dict[i][j]=data[k++];
}
if (k<=size)
dict[i][j+1]='\0';
}
for (i=0;i<sum;i++)
free(dict[i]);
free(dict);
free(num_words);
free(data);
return 0;
}
它无法编译,因为它显示了一个分段错误。更具体地说,-g 编译向我展示了以下内容:
* `./crossword' 中的错误:free():下一个尺寸无效(快速):0x0000000000fdf010 * ======= 回溯:========= /lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f7b54dc87e5] /lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7f7b54dd137a] /lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f7b54dd553c] ./填字游戏[0x400a97] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f7b54d71830] ./填字游戏[0x400699] ======= 内存映射:======== 00400000-00401000 r-xp 00000000 08:25 532064
/home/nikos/Desktop/ergasies/ergasia_4/填字游戏 00600000-00601000 r--p 00000000 08:25 532064
/home/nikos/Desktop/ergasies/ergasia_4/填字游戏 00601000-00602000 rw-p 00001000 08:25 532064
/home/nikos/Desktop/ergasies/ergasia_4/crossword 00fdf000-01000000 rw-p 00000000 00:00 0 [堆] 7f7b50000000-7f7b50021000 rw-p 00000000 00:00 0 7f7b50021000-7f7b54000000 ---p 00000000 00:00 0 7f7b54b3b000-7f7b54b51000 r-xp 00000000 08:25 529319
/lib/x86_64-linux-gnu/libgcc_s.so.1 7f7b54b51000-7f7b54d50000 ---p 00016000 08:25 529319
/lib/x86_64-linux-gnu/libgcc_s.so.1 7f7b54d50000-7f7b54d51000 rw-p 00015000 08:25 529319
/lib/x86_64-linux-gnu/libgcc_s.so.1 7f7b54d51000-7f7b54f11000 r-xp 00000000 08:25 542663
/lib/x86_64-linux-gnu/libc-2.23.so 7f7b54f11000-7f7b55111000 ---p 001c0000 08:25 542663
/lib/x86_64-linux-gnu/libc-2.23.so 7f7b55111000-7f7b55115000 r--p 001c0000 08:25 542663
/lib/x86_64-linux-gnu/libc-2.23.so 7f7b55115000-7f7b55117000 rw-p 001c4000 08:25 542663
/lib/x86_64-linux-gnu/libc-2.23.so 7f7b55117000-7f7b5511b000 rw-p 00000000 00:00 0 7f7b5511b000-7f7b55141000 r-xp 00000000 08:25 542656 /lib/x86_64-linux-gnu/ld-2.23.so 7f7b55323000-7f7b55326000 rw-p 00000000 00:00 0 7f7b5533f000-7f7b55340000 rw-p 00000000 00:00 0 7f7b55340000-7f7b55341000 r--p 00025000 08:25 542656
/lib/x86_64-linux-gnu/ld-2.23.so 7f7b55341000-7f7b55342000 rw-p 00026000 08:25 542656
/lib/x86_64-linux-gnu/ld-2.23.so 7f7b55342000-7f7b55343000 rw-p 00000000 00:00 0 7fff2dca9000-7fff2dcca000 rw-p 00000000 00:00 0
[堆栈] 7fff2dd02000-7fff2dd05000 r--p 00000000 00:00 0
[vvar] 7fff2dd05000-7fff2dd07000 r-xp 00000000 00:00 0
[vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0
[vsyscall] 中止(核心转储)
我还创建了一个数组来保存每个单词的大小。我没有双重释放任何指针,也找不到任何“数组外”的写作。任何人都可以指出我的代码中出现问题的地方吗?非常感谢:)
【问题讨论】:
-
与您自己的编码风格保持一致,并格式化您的代码以使其可读。特别是,当您打算将其展示给其他人时。哦,通常
for (i=0;i<=size-1;i++)我们会这样写for (i = 0; i < size; i++)。 -
Segfault 意味着您/您的程序可能尝试访问不值得您访问的内存位置。想一想。
-
我看到你已经得到了答案,但我仍然不清楚这个问题。您的错误提示似乎表明您确实编译并运行了您的应用程序,但您的问题声明说它没有编译。是哪个?
-
不,不,我没有设法编译,因为我没有为指针数组(又名字典)分配足够的空间。现在我准备好了
标签: c arrays linux segmentation-fault malloc