2016-12-14 56 views
2

當我在同一個指針上執行兩個連續的free()時,它給出了雙重空閒錯誤,但是當我嘗試在兩次之間釋放相同的指針時,我釋放了其他指針,但它沒有給出錯誤。爲什麼下面的代碼沒有給出雙倍的空閒錯誤?

#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()釋放內存空間由ptr,肯定有 已返回由以前調用malloc()calloc()realloc()指出。 否則,或者如果free(ptr)已被調用, 未定義的行爲發生。如果ptrNULL,則不執行操作 。

Undefined behavior表示無法保證將會發生什麼。你的程序可能會崩潰,它可能會表現出奇怪的行爲,或者(如你所見)它可能看起來工作正常。對你的代碼做一個看似無關的改變可以改變未定義的行爲本身的表現方式,所以它可能會開始崩潰或者可能會停止崩潰。

編輯:

通過運行等工具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) 

如果你使用一些其他的檢查來進行測試,你應該修改的問題更加具體。

相關問題