2017-01-24 1 views
1

나는 최근에 C에서의 malloc 기능에 관심이 있었고 흥미로운 행동을 관찰했습니다. malloc이 NULL이 된 후 첫 번째 'out of bounds'값처럼 보입니다 (또는 적어도 if에 의해 false로 간주되는 것을 반환합니다). malloc의 동작 : 처음에는 'out of bounds'값이 항상 NULL/0입니까?

i=0,d[0]=42.000000 
i=1,d[1]=42.000000 
i=2,d[2]=42.000000 
i=3,d[3]=42.000000 
i=4,d[4]=42.000000 
i=5,d[5]=42.000000 
i=6,d[6]=42.000000 
i=7,d[7]=42.000000 
i=8,d[8]=42.000000 
i=9,d[9]=42.000000 
out of bounds : i=10 
exited 'out of bounds loop' safely 

내 질문

은 다음과 같습니다 :

  • 이 문제가 예측 여기에 출력의

    int main(){ 
    
        int i; 
        double * d_ptr = malloc (10 * sizeof (double)); //malloc 10 double 
        for (i=0 ; i<10 ; i++){       // initialise them ... 
         d_ptr[i] = 42; 
        } 
    
        for (i=0 ;i <50 ; i++){ /// loop obviously trying to go out of bounds 
         if (d_ptr[i]){ 
          printf("i=%d,d[%d]=%f\n",i,i,d_ptr[i]); 
         } 
         else { 
          printf("out of bounds : i=%d\n",i); 
          break; 
         } 
        } 
    
        printf("exited 'out of bounds loop' safely\n"); 
        free(d_ptr); 
        return 0; 
    } 
    

    : 여기 는 그림인가? malloc을위한 다양한 변수 유형, 다른 크기를 시도했고, 항상 루프를 안전하게 종료했습니다. 자신의 '크기'까다로울 수, 또는 재 작성 많이 필요를 알고있는 경우

  • 이 예측 가능한 경우, 그것은 상황에서 포인터에 루프에 신뢰할 수있는 방법이 될 수있다?

  • 마지막으로, 더 깊은 설명은 무엇입니까? malloc을 수행합니까 메모리 공간을 한 단어 여분 할당 후 할당 하시겠습니까?
+3

경계를 벗어난 액세스는 정의되지 않은 동작입니다. 무엇이든 일어날 수 있습니다. 가장 확실하게 예측할 수 없습니다. – Barmar

+0

할당 한 후 메모리를 해제 한 다음 조금 더 작은 블록을 할당하고 새 블록의 끝에 여전히 '0'이 있는지 확인하십시오. – Barmar

답변

2

정의되지 않은 동작을 호출하면 아무 일도 발생할 수 없습니다. 프로그램이 충돌하거나 이상한 결과가 표시되거나 올바르게 작동하는 것처럼 보일 수 있습니다. 이 경우에는 후자가됩니다.

==22701== Memcheck, a memory error detector 
==22701== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
==22701== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info 
==22701== Command: /tmp/x1 
==22701== 
i=0,d[0]=42.000000 
i=1,d[1]=42.000000 
i=2,d[2]=42.000000 
i=3,d[3]=42.000000 
i=4,d[4]=42.000000 
i=5,d[5]=42.000000 
i=6,d[6]=42.000000 
i=7,d[7]=42.000000 
i=8,d[8]=42.000000 
i=9,d[9]=42.000000 
==22701== Invalid read of size 8 
==22701== at 0x4005C4: main (x1.c:13) 
==22701== Address 0x4c18090 is 0 bytes after a block of size 80 alloc'd 
==22701== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==22701== by 0x400579: main (x1.c:7) 
==22701== 
out of bounds : i=10 
exited 'out of bounds loop' safely 
==22701== 
==22701== HEAP SUMMARY: 
==22701==  in use at exit: 0 bytes in 0 blocks 
==22701== total heap usage: 1 allocs, 1 frees, 80 bytes allocated 
==22701== 
==22701== All heap blocks were freed -- no leaks are possible 
==22701== 
==22701== For counts of detected and suppressed errors, rerun with: -v 
==22701== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4) 

당신이 볼 수 있듯이,이 제대로 malloc 된 버퍼의 끝을지나 읽기로 인식되었다 Valgrind의에서이 프로그램을 실행

다음과 같은 결과를 주었다.

프로그램이 중단 될 수 있다고해서 그것이 의미하는 것은 아닙니다.

so 아니요이 동작은 예측할 수 없습니다.

2

"이 동작을 예측할 수 있습니까?" 아니요, undefined입니다. "마지막으로 malloc은 할당 할 메모리 공간을 한 단어 여분으로 할당합니까?" 아니, 최소한 내가 아는 모든 구현에서, 당신은 고의로 배열을 액세스하려고 시도해서는 안된다. 경우에 따라 UB에서 운이 좋을 수도 있으며 프로그램이 실행 된 후에도 예상대로 작동 할 것입니다. time travelling nasal dragons을주의하십시오.

+0

조언과 경비 용 여행에 모두 감사드립니다! 추운 사실을 기억하는 좋은 이미지보다 나은 것은 없습니다. –