2013-08-25 2 views
1

오류 해제 1000 바이트 :더블 무료 I 메모리 내부 할당 + 액세스 시간을 테스트하는 작은 프로그램 작성했습니다

#include <stdio.h> 
#include <stdlib.h> 

int main (int argc, char *argv[]) 
{ 
    if (argc < 2) 
    { 
     printf("fail, %d args\n", argc); 
     return 1; 
    } 

    char *a; 
    int i; 

    long long int stress_size = atoi(argv[1]); 

    a = malloc(stress_size); 
    printf("%Ld bytes allocated\n", stress_size); 
    printf("a is here:  %p\n", a); 
    for (i = 0; i < stress_size; ++i) 
    { 
     a++; 
     *a = 4; 
    } 
    printf("a is here now: %p\n", a); 

    a -= stress_size/sizeof(char); 
    printf("back to original position\n"); 
    printf("a is here now: %p\n", a); 
    printf("pre-free\n"); 
    free(a); 
    printf("free ok\n"); 
    return 0; 
} 

프로그램도 높은 값 (400M 바이트) 작동을하지만 exacts에 실패 200, 600, 1000, 1400, ... 일반 400N + (200)에 난 정말 이해가 안 : 바이트 수 :로 1000

$ ./main 1000 
1000 bytes allocated 
a is here:  0x1c81010 
a is here now: 0x1c813f8 
back to original position 
a is here now: 0x1c81010 
pre-free 
*** glibc detected *** ./main: double free or corruption (!prev): 0x0000000001c81010 *** 
======= Backtrace: ========= 
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7f9133438d76] 
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7f913343daac] 
./main[0x4008cf] 
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f91333e0ead] 
./main[0x4006e9] 
======= Memory map: ======== 
00400000-00401000 r-xp 00000000 08:03 928478        /home/alex/programmazione/c/memory_long_stress_test/main 
00600000-00601000 rw-p 00000000 08:03 928478        /home/alex/programmazione/c/memory_long_stress_test/main 
01c81000-01ca2000 rw-p 00000000 00:00 0         [heap] 
7f912c000000-7f912c021000 rw-p 00000000 00:00 0 
7f912c021000-7f9130000000 ---p 00000000 00:00 0 
7f91331ac000-7f91331c1000 r-xp 00000000 08:03 1966084     /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f91331c1000-7f91333c1000 ---p 00015000 08:03 1966084     /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f91333c1000-7f91333c2000 rw-p 00015000 08:03 1966084     /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f91333c2000-7f9133542000 r-xp 00000000 08:03 1966099     /lib/x86_64-linux-gnu/libc-2.13.so 
7f9133542000-7f9133742000 ---p 00180000 08:03 1966099     /lib/x86_64-linux-gnu/libc-2.13.so 
7f9133742000-7f9133746000 r--p 00180000 08:03 1966099     /lib/x86_64-linux-gnu/libc-2.13.so 
7f9133746000-7f9133747000 rw-p 00184000 08:03 1966099     /lib/x86_64-linux-gnu/libc-2.13.so 
7f9133747000-7f913374c000 rw-p 00000000 00:00 0 
7f913374c000-7f91337b3000 r-xp 00000000 08:03 2502762     /usr/lib/x86_64-linux-gnu/libgmp.so.10.0.5 
7f91337b3000-7f91339b3000 ---p 00067000 08:03 2502762     /usr/lib/x86_64-linux-gnu/libgmp.so.10.0.5 
7f91339b3000-7f91339bb000 rw-p 00067000 08:03 2502762     /usr/lib/x86_64-linux-gnu/libgmp.so.10.0.5 
7f91339bb000-7f9133a3c000 r-xp 00000000 08:03 1966096     /lib/x86_64-linux-gnu/libm-2.13.so 
7f9133a3c000-7f9133c3b000 ---p 00081000 08:03 1966096     /lib/x86_64-linux-gnu/libm-2.13.so 
7f9133c3b000-7f9133c3c000 r--p 00080000 08:03 1966096     /lib/x86_64-linux-gnu/libm-2.13.so 
7f9133c3c000-7f9133c3d000 rw-p 00081000 08:03 1966096     /lib/x86_64-linux-gnu/libm-2.13.so 
7f9133c3d000-7f9133c5d000 r-xp 00000000 08:03 1966102     /lib/x86_64-linux-gnu/ld-2.13.so 
7f9133e37000-7f9133e3a000 rw-p 00000000 00:00 0 
7f9133e59000-7f9133e5c000 rw-p 00000000 00:00 0 
7f9133e5c000-7f9133e5d000 r--p 0001f000 08:03 1966102     /lib/x86_64-linux-gnu/ld-2.13.so 
7f9133e5d000-7f9133e5e000 rw-p 00020000 08:03 1966102     /lib/x86_64-linux-gnu/ld-2.13.so 
7f9133e5e000-7f9133e5f000 rw-p 00000000 00:00 0 
7fff41490000-7fff414b1000 rw-p 00000000 00:00 0       [stack] 
7fff41511000-7fff41512000 r-xp 00000000 00:00 0       [vdso] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 

계속 저도 같은 문제가 영향을 미치는 것을 발견 노력도 값 왜 일어나는거야?

나는이 사용 GCC (데비안 4.7.2-5) 4.7.2 리눅스 3.2.0-4-AMD64 # 1 SMP 데비안 3.2.46-1 x86_64에 GNU/리눅스에서 컴파일.

+3

, 당신이 증가하는 ** 전 ** 할당 중 ... –

+0

a = a + sizeof (char)를 저장하지 않으므로 다음과 같이 설정해야합니다. a - = stress_size; 그러나 [i] = 4를 쓰는 것이 더 쉬우 며, 결코 변경하지 않아야합니다. – dcaswell

+0

@OliCharlesworth : 그것은 아주 어리석은 부주의였다. 나는 그것이 작동하는 것처럼 보입니다. – Blex

답변

1

당신이 소유하고있는 것보다 한 곳을 쓰고 있습니다. BTW

for (i = 0; i < stress_size; ++i) 
{ 
    *a = 4; // Setting array a_original[0] to a_original[stress_size-1]. 
    a++; 
} 

:

for (i = 0; i < stress_size; ++i) 
{ 
    a++; 
    *a = 4; // Bad: Setting array a_original[1] to a_original[stress_size]. 
} 

변경에 (@Oli 찰스 워드 주석 참조) 더 낮은 여기 l 하시겠습니까 : 루프에서 printf("%Ld bytes allocated\n"...

+0

% printf 안에있는 Ld는 괜찮습니다. long long 변수를 사용하고 있습니다. 그렇지 않으면 경고를받습니다. – Blex

+0

@Blex, "% Ld"을 (를) 허용하는 컴파일러는 무엇입니까? "% lld"는'long long'의 표준입니다. – chux

+0

나는 항상 "% Ld"가 정확하다고 생각했습니다. gcc는 경고없이 컴파일합니다. – Blex