簡體   English   中英

C-通過調用fclose()轉儲內核

[英]C - Dumping cores with call to fclose()

我的代碼存在段錯誤,我不知道出什么問題了。 我已盡力簡化了,但仍然找不到問題。

C文件test.c:

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

struct container {
   void *A[3], *B[3], *C[3], *D[3];
   int x, y, z;
};

int main (int argc, char* argv[]) {
   struct container *cont = malloc (sizeof cont);
   FILE* fh = fopen( argv[1], "r" );
   if( fh == NULL ) return 0;
   fscanf(fh, "%d %d", &cont->y,  &cont->z);
   fclose( fh );
   free( cont );

   return 0;
}

test.txt的內容

1 1

通過gdb執行並運行:

$ gcc --version
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -Wall -g test.c && gdb a.out 
GNU gdb (GDB) 7.6.1-ubuntu
Copyright (C) 2013 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".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dberg/ITX/Cells/test/a.out...done.
(gdb) break 26
Breakpoint 1 at 0x400739: file test.c, line 26.
(gdb) run test.txt
Starting program: /home/dberg/ITX/Cells/test/a.out test.txt

Breakpoint 1, main (argc=2, argv=0x7fffffffdf48) at test.c:26
26         fclose( fh );
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x1) at malloc.c:2892
2892    malloc.c: No such file or directory.
(gdb) 

刪除任何一個未使用的struct成員將允許代碼執行而不會出錯。 將任何未使用的struct成員移動到struct的末尾或減小任何1個數組或所有數組的大小也可以使代碼成功執行。 對於段錯誤,也必須存在fscanf()調用

我的語法哪里有問題,為什么結構的大小對此錯誤如此重要?

有一個*在缺少struct container *cont = malloc (sizeof cont); ,您需要sizeof *cont

Bzzzt! 不是fclose失敗,而是您沒有分配足夠的空間來容納(結構容器)類型。 這是一個語義而不是句法問題。

假設您有一個名為“ stuff”的文件,其中包含:

1,2,3

並且您的程序名為doit.c,它將讀取該文件(檢查是否有足夠的參數,檢查fopen和malloc的返回值等),

//you might want to carry a shorter name around,
typedef struct container_s
{
   void *A[3], *B[3], *C[3], *D[3];
   int x, y, z;
} container;
//how big is a (struct container)?  depends.  How big is a (void*) or an (int)?
//Suppose 32-bit, then you have 12x4+3*4=60 bytes.
//Suppose 64-bit pointer, and 32-bit integer, then you have 12x8+3*4=108 bytes.

int main (int argc, char* argv[])
{
   struct container* cont;
   FILE* fh = fopen( argv[1], "r" );
   char* filename=NULL;
   //you really should not examine argv[1] if there is no argument...
   if(argc<1) {
       printf("usage: stuff <filename>\n");
       exit(EXIT_FAILURE);
   }
   filename=argv[1];
   //allocate space for a (struct container_s)
   if( !(cont = malloc(sizeof(struct container))) ) {
        printf("error: cannot allocate container\n");
   }
   //check that file opens successfully,
   if(!(fh=fopen(filename,"r" ))) {
        printf("error: cannot open %s\n",filename);
        return 0;
   }
   //read your vector (x,y,z),
   fscanf(fh,"%d,%d,%d",&(cont->x),&(cont->y),&(cont->z));
   //for fun, print the (x,y,z) coordinates,
   printf("stuff(%d,%d,%d)\n",cont->x,cont->y,cont->z);
   fclose(fh);
   free(cont);

   return 0;
}

編譯並運行上面的代碼,您會得到,

./doit stuff
stuff(1,2,3)

請檢查庫函數(fopen,malloc)的返回值和邊界檢查數組(例如argv [])。 哦,您可能要為容器中的A [],B [],C []和D []命名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM