2016-12-14 2 views
2

私は同じポインタ上に2つの連続したfree()を実行すると、2回の空きエラーが発生しますが、2回同じポインタを解放しようとすると、別のポインタを解放してもエラーは発生しません。次のコードがダブルフリーエラーを表示しないのはなぜですか?

#include <stdio.h>                
#include <stdlib.h>                
int main(){                    
    long int*ptr;                
    int *ptr1;                 

    ptr = malloc (1);               
    ptr1 = malloc (1);               

    printf ("%ld\n", ptr[-1]);             
    free (ptr);                 
    printf ("%ld\n", ptr[-1]);             
    free (ptr1);                 
    free (ptr);                 
    free (ptr1);                 
    free (ptr);                 
    free (ptr1);                 
    return 0;                 
} 
+6

ダブルフリーで最初にエラーを返す必要はありません – user3528438

+0

これは単に未定義の動作です。 – George

+0

*** './app 'のエラー:ダブルフリーまたは破損(fasttop):0x0000563f04897010 *** –

答えて

6

ダブルfreeは、セグメンテーションフォールトが発生しますと判断一切の約束はありません。 man pageから

free()は、メモリ空間が がmalloc()calloc()またはrealloc()に前回の呼び出しによって返されていなければなりませんptr、によって指さ解放します。 これ以外の場合、またはfree(ptr)が既に呼び出されている場合は、 未定義の動作が発生します。ptrNULLの場合、操作は行われません。 です。

Undefined behaviorは、何が起こるかに関する保証がないことを意味します。プログラムがクラッシュしたり、奇妙な動作が発生したり、(見たように)正しく動作するように見える可能性があります。コードに一見無関係な変更を加えると、定義されていない動作がどのように現れるかが変更されるため、クラッシュする可能性があります。

EDIT:

は、Valgrindのようなツールを介して、プログラムを実行し、トビーによって示唆されているように、これらのタイプのエラーを探すために、具体的な場所で追加チェックを置き、物事がうまく行っている場所を正確に教えてくれます。

ただし、このようなツールがないと、未定義の動作を呼び出すと、すべての賭けはオフになります。

2

おそらく、誤ったツールを使用してプログラムをテストしている可能性があります。私はあなたのテストプログラムをビルド時Valgrindのは、確かにエラーの多くを報告します。

gcc -std=c11 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds  41147878.c -o 41147878 
valgrind ./41147878 
==30744== Memcheck, a memory error detector 
==30744== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==30744== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info 
==30744== Command: ./41147878 
==30744== 
==30744== Invalid read of size 8 
==30744== at 0x10876C: main (41147878.c:10) 
==30744== Address 0x51d5038 is 8 bytes before a block of size 1 alloc'd 
==30744== at 0x4C2ABAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x108751: main (41147878.c:7) 
==30744== 
0 
==30744== Invalid read of size 8 
==30744== at 0x108797: main (41147878.c:12) 
==30744== Address 0x51d5038 is 8 bytes before a block of size 1 free'd 
==30744== at 0x4C2BDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x10878E: main (41147878.c:11) 
==30744== Block was alloc'd at 
==30744== at 0x4C2ABAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x108751: main (41147878.c:7) 
==30744== 
0 
==30744== Invalid free()/delete/delete[]/realloc() 
==30744== at 0x4C2BDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x1087C5: main (41147878.c:14) 
==30744== Address 0x51d5040 is 0 bytes inside a block of size 1 free'd 
==30744== at 0x4C2BDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x10878E: main (41147878.c:11) 
==30744== Block was alloc'd at 
==30744== at 0x4C2ABAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x108751: main (41147878.c:7) 
==30744== 
==30744== Invalid free()/delete/delete[]/realloc() 
==30744== at 0x4C2BDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x1087D1: main (41147878.c:15) 
==30744== Address 0x51d5090 is 0 bytes inside a block of size 1 free'd 
==30744== at 0x4C2BDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x1087B9: main (41147878.c:13) 
==30744== Block was alloc'd at 
==30744== at 0x4C2ABAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x10875F: main (41147878.c:8) 
==30744== 
==30744== Invalid free()/delete/delete[]/realloc() 
==30744== at 0x4C2BDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x1087DD: main (41147878.c:16) 
==30744== Address 0x51d5040 is 0 bytes inside a block of size 1 free'd 
==30744== at 0x4C2BDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x10878E: main (41147878.c:11) 
==30744== Block was alloc'd at 
==30744== at 0x4C2ABAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x108751: main (41147878.c:7) 
==30744== 
==30744== Invalid free()/delete/delete[]/realloc() 
==30744== at 0x4C2BDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x1087E9: main (41147878.c:17) 
==30744== Address 0x51d5090 is 0 bytes inside a block of size 1 free'd 
==30744== at 0x4C2BDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x1087B9: main (41147878.c:13) 
==30744== Block was alloc'd at 
==30744== at 0x4C2ABAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==30744== by 0x10875F: main (41147878.c:8) 
==30744== 
==30744== 
==30744== HEAP SUMMARY: 
==30744==  in use at exit: 0 bytes in 0 blocks 
==30744== total heap usage: 3 allocs, 7 frees, 1,026 bytes allocated 
==30744== 
==30744== All heap blocks were freed -- no leaks are possible 
==30744== 
==30744== For counts of detected and suppressed errors, rerun with: -v 
==30744== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0) 

、あなたのテストを行うために、いくつかの他のチェッカーを使用していた場合、あなたはより具体的に質問を編集する必要があります。

関連する問題