7

これは私のCプログラムです:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#define FALSE 0
#define TRUE 1

typedef struct _Frag
{
  struct _Frag *next;
  char *seq;
  int x1;
  int length;
} Frag;

typedef struct _Fragment
{
  int type;
  Frag *frag_list;
} Fragment;

static void
free_frags (Fragment * frags, int len)
{
  int i;
  for (i = 0; i < len; i++)
    {
      Fragment *fragment = &frags[i];
      Frag *current = fragment->frag_list;

      while (current != NULL)
    {
      free (current->seq);
      fragment->frag_list = current->next;
      free (current);
      current = fragment->frag_list;
    }

      /* to do : free fragment */
      free (fragment);
      fragment = NULL;
    }
  free (frags);
}

int
main ()
{
  Fragment *frags = (Fragment *) malloc (10 * sizeof (Fragment));
  int i, j;
  for (i = 0; i < 10; i++)
    {
      Fragment *fragment = &frags[i];
      fragment->frag_list = (Frag *) malloc (1 * sizeof (Frag));
      Frag *frag = fragment->frag_list;
      frag->seq = malloc (6 * sizeof (char));
      strcpy (frag->seq, "55555");
      frag->next = (Frag *) malloc (1 * sizeof (Frag));
      frag = frag->next;
      frag->seq = malloc (6 * sizeof (char));
      strcpy (frag->seq, "55555");
      frag->next=NULL;
    }
  free_frags (frags, 10);
  return 0;
}

gdb でデバッグすると、エラー メッセージは次のようになります。

(gdb) run a.out 
..........................
..........................
09574000-09595000 rwxp 00000000 00:00 0          [heap]
b7e00000-b7e21000 rwxp 00000000 00:00 0 
b7e21000-b7f00000 ---p 00000000 00:00 0 
b7f2e000-b7f4b000 r-xp 00000000 08:08 298454     /usr/lib/libgcc_s.so.1
b7f4b000-b7f4c000 rwxp 0001c000 08:08 298454     /usr/lib/libgcc_s.so.1
b7f4c000-b7f4d000 rwxp 00000000 00:00 0 
b7f4d000-b808d000 r-xp 00000000 08:08 67152259   /lib/libc-2.10.1.so
b808d000-b808f000 r-xp 0013f000 08:08 67152259   /lib/libc-2.10.1.so
b808f000-b8090000 rwxp 00141000 08:08 67152259   /lib/libc-2.10.1.so
b8090000-b8094000 rwxp 00000000 00:00 0 
b80ae000-b80af000 r-xp 00000000 00:00 0          [vdso]
b80af000-b80cb000 r-xp 00000000 08:08 67152744   /lib/ld-2.10.1.so
b80cb000-b80cc000 r-xp 0001b000 08:08 67152744   /lib/ld-2.10.1.so
b80cc000-b80cd000 rwxp 0001c000 08:08 67152744   /lib/ld-2.10.1.so
bfc0f000-bfc24000 rw-p 00000000 00:00 0          [stack]

Program received signal SIGABRT, Aborted.
0xb80ae424 in __kernel_vsyscall ()
(gdb) where
#0  0xb80ae424 in __kernel_vsyscall ()
#1  0xb7f77411 in raise () from /lib/libc.so.6
#2  0xb7f78c12 in abort () from /lib/libc.so.6
#3  0xb7fb271d in __libc_message () from /lib/libc.so.6
#4  0xb7fb8581 in malloc_printerr () from /lib/libc.so.6
#5  0xb7fb9c82 in _int_free () from /lib/libc.so.6
#6  0xb7fbcd4d in free () from /lib/libc.so.6
#7  0x08048488 in free_frags (frags=0x9574008, len=10) at main.c:41
#8  0x080485b3 in main () at main.c:65
(gdb) 

valgrind メッセージは次のとおりです。

==2832== Memcheck, a memory error detector.
==2832== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==2832== Using LibVEX rev 1884, a library for dynamic binary translation.
==2832== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==2832== Using valgrind-3.4.1, a dynamic binary instrumentation framework.
==2832== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==2832== For more details, rerun with: -v
==2832== 
==2832== Invalid read of size 4
==2832==    at 0x8048442: free_frags (main.c:31)
==2832==    by 0x80485B2: main (main.c:66)
==2832==  Address 0x418b034 is 12 bytes inside a block of size 80 free'd
==2832==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==2832==    by 0x8048487: free_frags (main.c:42)
==2832==    by 0x80485B2: main (main.c:66)
==2832== 
==2832== Invalid write of size 4
==2832==    at 0x8048460: free_frags (main.c:36)
==2832==    by 0x80485B2: main (main.c:66)
==2832==  Address 0x418b034 is 12 bytes inside a block of size 80 free'd
==2832==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==2832==    by 0x8048487: free_frags (main.c:42)
==2832==    by 0x80485B2: main (main.c:66)
==2832== 
==2832== Invalid read of size 4
==2832==    at 0x8048471: free_frags (main.c:38)
==2832==    by 0x80485B2: main (main.c:66)
==2832==  Address 0x418b034 is 12 bytes inside a block of size 80 free'd
==2832==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==2832==    by 0x8048487: free_frags (main.c:42)
==2832==    by 0x80485B2: main (main.c:66)
==2832== 
==2832== Invalid free() / delete / delete[]
==2832==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==2832==    by 0x8048487: free_frags (main.c:42)
==2832==    by 0x80485B2: main (main.c:66)
==2832==  Address 0x418b030 is 8 bytes inside a block of size 80 free'd
==2832==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==2832==    by 0x8048487: free_frags (main.c:42)
==2832==    by 0x80485B2: main (main.c:66)
==2832== 
==2832== Invalid free() / delete / delete[]
==2832==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==2832==    by 0x80484A5: free_frags (main.c:45)
==2832==    by 0x80485B2: main (main.c:66)
==2832==  Address 0x418b028 is 0 bytes inside a block of size 80 free'd
==2832==    at 0x4023EBA: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==2832==    by 0x8048487: free_frags (main.c:42)
==2832==    by 0x80485B2: main (main.c:66)
==2832== 
==2832== ERROR SUMMARY: 55 errors from 5 contexts (suppressed: 13 from 1)
==2832== malloc/free: in use at exit: 0 bytes in 0 blocks.
==2832== malloc/free: 41 allocs, 51 frees, 520 bytes allocated.
==2832== For counts of detected errors, rerun with: -v
==2832== All heap blocks were freed -- no leaks are possible.

それらを修正するのを手伝ってください、ありがとう。

4

6 に答える 6

10

複数の問題があります。

ここでは、5 文字のスペースを割り当てますが、6 をコピーします (文字列の末尾にあるヌル ターミネータにもスペースが必要です)。

  frag->seq = malloc (5 * sizeof (char));
  strcpy (frag->seq, "55555");

同じ時点で、割り当てfrag->nextた秒数を設定することはありません。ルーチンのループが雑草に流れないように、fragに設定する必要があります。NULLwhilefree_frag

3番目の問題は次のとおりです。

  /* to do : free fragment */
  free (fragment);

を解放fragmentしますが、それは受信したブロック全体ではありませんmalloc。一度に割り当てた 10 個のフラグメントの単一ブロックの 1 つに過ぎません。後者はそのブロックを適切にfree(frags)解放するので、そのバグのある行を削除するだけです。

于 2009-09-03T06:52:41.667 に答える
7

配列の中央を解放しようとしています。

Fragment *fragment = &frags[i];
...
...
/* to do : free fragment */
free (fragment);
fragment = NULL;
于 2009-09-03T06:44:52.607 に答える
7

これらの行にはBufferoverflowがあるようです

  frag->seq = malloc (5 * sizeof (char));
  strcpy (frag->seq, "55555");

文字列55555には、割り当てられた 5 バイト以外のメモリにも書き込まれる終端のゼロ文字も含まれるためです。

strdup()代わりに、文字列を割り当ててコピーする which を使用できます

  frag->seq = strdup("55555");
于 2009-09-03T06:49:23.063 に答える
3

frag_listポインターのリンクされたリストとして扱ってFragいますが、リストを作成するときにターミネーターを入れていません。

これを試して:

int
main ()
{
  Fragment *frags = (Fragment *) malloc (10 * sizeof (Fragment));
  int i, j;
  for (i = 0; i < 10; i++)
    {
      Fragment *fragment = &frags[i];
      fragment->frag_list = (Frag *) malloc (1 * sizeof (Frag));
      Frag *frag = fragment->frag_list;
      frag->seq = malloc (5 * sizeof (char));
      strcpy (frag->seq, "55555");
      frag->next = (Frag *) malloc (1 * sizeof (Frag));
      frag = frag->next;
      frag->seq = malloc (5 * sizeof (char));
      strcpy (frag->seq, "55555");
      frag->next = NULL; // <--------------------- This is what you need to do
    }
  free_frags (frags, 10);
  return 0;
}

問題は、メモリの新しいブロックを作成するときにmalloc()、コンパイラや OSそれを無効にする可能性があることですが、それは単にガベージを与える可能性が高いということです。free()そのガベージをしようとすると、クラッシュします。

于 2009-09-03T06:45:01.017 に答える
2

Frag.nextポインターを (free_frags() で) センチネルとして使用する場合は、コードのどこかでそれを NULL に設定する必要があります。

また、注意してください。Frag.seqに 5 文字を割り当てるために malloc() を使用しており、そのスペースに NULL で終了しない文字列をコピーしています。

于 2009-09-03T06:43:48.040 に答える
0

自分のものではないメモリ アドレスを参照しています。これは、free_frags() 関数、具体的には 41 行目の free (fragment); で発生しています。.

于 2009-09-03T06:43:49.257 に答える