关于fopen的Segfault c

时间:2018-04-17 20:25:59

标签: c segmentation-fault fopen

在下面的代码中我得到了一个seg.fault,我不知道为什么会发生这种情况,因为我认为我将正确的参数传递给fopen

编译:

gcc -o testloadfile testloadfile.c

正在进行尝试:

首次尝试

./testloadfile "correctme.txt"

第二次尝试

 sudo ./testloadfile correctme.txt 

testloadfile.c的同一文件夹中,我有.txt名为correctme.txt

代码如下

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

static void load_array(const char* file_name){
  char *read_sentence;
  char buffer[2048];
  char a[100][100];
  int buf_size = 2048;
  FILE *fp;
  int j = 0, c = 0;

  printf("\nLoading data from file...\n");
  printf("%s \n", file_name); //prints correctme.txt  
  fp = fopen(file_name,"r"); //error happens here
  printf("This line won't be printed \n"); 
  if(fp == NULL){
    fprintf(stderr,"main: unable to open the file");
    exit(EXIT_FAILURE);
  }

 read_sentence = malloc((2048+1)*sizeof(char));

 read_sentence = fgets(buffer,buf_size,fp);

  for(int i = 0; i < strlen(read_sentence); i++) {
    a[j][c++] = read_sentence[i];
    if(read_sentence[i] == ' ' || read_sentence[i] == '.' || read_sentence[i] == ',') {
        j++;
        c = 0;
        continue;
    }   
  }

  free(read_sentence);

  for(int i = 0; i < 100; i++) 
    printf("%s\n", a[i]);

  fclose(fp);
  printf("\nData loaded\n");
}

int main(int argc, char const *argv[]) {
  if(argc < 2) {
    printf("Usage: ordered_array_main <file_name>\n");
    exit(EXIT_FAILURE);
  }

  load_array(argv[1]);

}

这是上面提到的文件夹enter image description here

这是gcc -g testloadfile testloadfile.c

的输出
testloadfile: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o:(.fini+0x0): first defined here
testloadfile: In function `data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:(.data+0x0): first defined here
testloadfile: In function `data_start':
(.data+0x8): multiple definition of `__dso_handle'
/usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o:(.data+0x0): first defined here
testloadfile:(.rodata+0x0): multiple definition of `_IO_stdin_used'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here
testloadfile: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
testloadfile: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o:(.init+0x0): first defined here
/tmp/cc0ye2Ms.o: In function `main':
/home/zenoraiser/Scrivania/Università/Secondo Anno/Algoritmi/1718/LAB/Progetto/Esercizio2/testloadfile.c:42: multiple definition of `main'
testloadfile:(.text+0x346): first defined here
/usr/lib/gcc/x86_64-linux-gnu/5/crtend.o:(.tm_clone_table+0x0): multiple definition of `__TMC_END__'
testloadfile:(.data+0x10): first defined here
/usr/bin/ld: error in testloadfile(.eh_frame); no .eh_frame_hdr table will be created.
collect2: error: ld returned 1 exit status

然后我做了ulimit -c unlimited

之后我用./testloadfile "correctme.txt"

运行程序

最后我使用了gdb ./bynary core,这是它的输出

GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
./bynary: No such file or directory.
/home/zenoraiser/Scrivania/Università/Secondo Anno/Algoritmi/1718/LAB/Progetto/Esercizio2/core: No such file or directory.

(对不起,我将尝试了解如何使用最后一个命令)

1 个答案:

答案 0 :(得分:3)

实际的seg故障可能在这一行:

 free(read_sentence);

请务必记住printf()将输出发送到缓存的stdout。因此,如果发生seg故障,您发送给它的东西不一定会打印出来。

至于seg故障本身,让我们看看这些行:

read_sentence = malloc((2048+1)*sizeof(char));

read_sentence = fgets(buffer,buf_size,fp);

看起来你认为你正在分配read_sentence,然后将从fp读取的数据放入其中(事实上代码会像这样发生),但事实并非如此。

相反,您将数据读入buffer,然后将read_sentence设置为 buffer的地址。

然后你做了你的操作,我们回到我指出的第一行:

free(read_sentence);

这不会释放上面malloc()调用中分配的内存,而是释放堆栈中的buffer,因此不能free() - 编辑。另外请注意,您最初为read_sentence分配的内存现已泄露,您将无法释放它。

最好的解决方案是将read_sentence(以及malloc()free()对)全部放在一起,然后在buffer内进行操作。< / p>

相关问题