【问题标题】:C-Segmentation faultC 段错误
【发布时间】: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&lt;=size-1;i++) 我们会这样写for (i = 0; i &lt; size; i++)
  • Segfault 意味着您/您的程序可能尝试访问不值得您访问的内存位置。想一想。
  • 我看到你已经得到了答案,但我仍然不清楚这个问题。您的错误提示似乎表明您确实编译并运行了您的应用程序,但您的问题声明说它没有编译。是哪个?
  • 不,不,我没有设法编译,因为我没有为指针数组(又名字典)分配足够的空间。现在我准备好了

标签: c arrays linux segmentation-fault malloc


【解决方案1】:

这里没有分配足够的空间

dict=malloc(sum);

应该是

dict = malloc(sum * sizeof(*dict));

因为你需要sum大小为void *的元素,但最好写成sizeof(*dict),因为这样代码就独立于dict的类型,如果你改了就不需要了修复你的malloc()

这看起来也很可疑,

num_words=malloc(sum);

您怎么知道每个单词的字符数与文件中的行数一样多?

【讨论】:

  • 天哪,我已经查看我的代码 2 天了,就是这样。我以为我缺乏更重要的知识。你让我松了一口气。真的很感谢你借给我一双眼睛!
  • @NikosNik 不客气。如果您使用支持valgrind 的程序员友好型操作系统,您可以进一步检查您的代码是否存在更多问题,其中一些问题可能很难找到。另外,使用更多的空格,dict=malloc ... 是可怕的风格。编译器可以立即看到dict=malloc 中有 3 个“tokens”,但人类可能需要多加注意才能注意到这一点。
  • 是的,谢谢你的信息。我会尝试改善代码的外观。在询问之前使用了 valgrind 但无法找到解决方案
猜你喜欢
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 2016-09-18
  • 1970-01-01
相关资源
最近更新 更多