第一個循環:
count == 0
a[count] = i
a = realloc(1 int)
count++
第二環:
count == 1
a[count] = i /* OUT OF BOUNDS */
Valgrind或ASAN會趕上這個錯誤的時候了。如果沒有它們,純粹是巧合,它不會被人注意到。
$ cc -g -o test test.c
$ valgrind ./test
==25080== Memcheck, a memory error detector
==25080== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==25080== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==25080== Command: ./test
==25080==
Enter a positive integer: 4
Factors of 4 are: 0 1
==25080== Invalid write of size 4
==25080== at 0x4006D0: main (test.c:16)
==25080== Address 0x51db914 is 0 bytes after a block of size 4 alloc'd
==25080== at 0x4C2D13F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25080== by 0x40071A: main (test.c:18)
==25080==
==25080== Invalid read of size 4
==25080== at 0x4006E6: main (test.c:17)
==25080== Address 0x51db914 is 0 bytes after a block of size 4 alloc'd
==25080== at 0x4C2D13F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25080== by 0x40071A: main (test.c:18)
==25080==
1 2
2 4
==25080==
==25080== HEAP SUMMARY:
==25080== in use at exit: 0 bytes in 0 blocks
==25080== total heap usage: 6 allocs, 6 frees, 2,088 bytes allocated
==25080==
==25080== All heap blocks were freed -- no leaks are possible
==25080==
==25080== For counts of detected and suppressed errors, rerun with: -v
==25080== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 0 from 0)
$ clang -fsanitize=address -g -o test test.c
$ ./test
Enter a positive integer: 5
Factors of 5 are: 0 1
=================================================================
==23697==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eff4 at pc 0x0000004ffdec bp 0x7ffc641c5eb0 sp 0x7ffc641c5ea8
WRITE of size 4 at 0x60200000eff4 thread T0
#0 0x4ffdeb (/home/dlin/test+0x4ffdeb)
#1 0x7faaee64f510 (/usr/lib/libc.so.6+0x20510)
#2 0x4186a9 (/home/dlin/test+0x4186a9)
0x60200000eff4 is located 0 bytes to the right of 4-byte region [0x60200000eff0,0x60200000eff4)
allocated by thread T0 here:
#0 0x4c83d0 (/home/dlin/test+0x4c83d0)
#1 0x4ffe8d (/home/dlin/test+0x4ffe8d)
#2 0x7faaee64f510 (/usr/lib/libc.so.6+0x20510)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/dlin/test+0x4ffdeb)
Shadow bytes around the buggy address:
0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[04]fa
0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==23697==ABORTING
不能使用'realloc的()'如果你正確使用它的返回值來覆蓋其輸入指針。如果失敗會發生什麼? –
不確定你爲什麼使用'realloc'。第一個「malloc」分配的空間比需要的多。 – user3386109
你沒有測試'malloc()'和'realloc()'的返回值。 – TonyB