当我在同一个指针上连续两个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;
}
答案 0 :(得分:6)
没有承诺双free
会导致分段错误。
来自man page:
free()
释放ptr
指向的内存空间,它必须具有 通过之前的malloc()
,calloc()
或realloc()
来电回复。 否则,或者之前已经调用free(ptr)
, 发生未定义的行为。如果ptr
为NULL
,则不执行任何操作 进行。
Undefined behavior表示无法保证会发生什么。您的程序可能会崩溃,可能会出现奇怪的行为,或者(正如您所见)它可能会正常工作。对代码进行看似无关的更改可能会改变未定义行为的显示方式,因此可能会崩溃或者可能会停止崩溃。
编辑:
如Toby所建议的那样,通过Valgrind等工具运行程序,专门针对这些类型的错误进行了额外的检查,并会准确地告诉您出错的地方。
如果没有这样的工具,如果你调用未定义的行为,所有的赌注都会关闭。
答案 1 :(得分: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)
如果您使用其他检查器进行测试,则应将问题编辑为更具体。