2011-09-12 2 views
1

나는 2 차원 배열을 통해 malloc에 ​​작업을 수행하는이 방법을 사용, 내 소스는 http://c-faq.com/aryptr/dynmuldimary.htmlModify malloc strategy for 2D Array so malloc succeeds 같습니다2 차원 어레이가있는 C malloc : 세그먼트 화 오류가없는 이유는 무엇입니까?

int 
main(int argc, char *argv[]) 
{ 
    long **array = NULL; 

    array = malloc(5 * sizeof(long *)); 
    for (int i = 0; i < 5; i++) 
     array[i] = malloc(3 * sizeof(long)); 

    array[4][2] = 515; 
    array[4][3] = 212; 
    array[4][10000] = 3; 

    printf("%ld\n", array[4][10000]); 

    return 0; 
} 

내 질문은, 는 이유는 어떤의 실행에 세그먼트 오류를 ​​얻을하지 않습니다 돌아 오기 전에 마지막 세 줄? 안전합니까 (공존의 존재를 무시함)?

+1

c는 배열의 경계를 검사하지 않으므로 보통 유효한 메모리에 액세스하고 있는지 확인하기 위해 OS에 의존합니다. –

+2

C (C++이 아님)를 수행하는 경우 많은 사람들이 다른 유형의 포인터를 생략하는 것을 권장하지 않습니다. 특히'array = (long **) malloc (5 * sizeof (long *));'을'array = malloc (5 * sizeof * array);로 변경하면 배열의 타입을 변경하면 '는 여전히'malloc'을위한 정확한 크기를 생성 할 것입니다. (다른 호출'array [i] = malloc (3 * sizeof ** array);도 마찬가지입니다.) –

+0

그래서 내 경계를 벗어나 액세스하려고하지 않는 한 "안전"합니다. ? –

답변

0

운영 체제는 응용 프로그램에 메모리 (일반적으로 4KB)를 할당합니다. 효율성을 위해 거대한 페이지 (예 : 2MB)를 사용할 수 있습니다.

첫 페이지는 할당되지 않으며 페이지에 액세스하려고 시도하면 세그먼트 오류가 발생합니다. 예 : 0 - 4095의 모든 포인터에 액세스하면 대부분의 시스템에서 세그먼트 화 오류가 발생합니다.

그러나 페이지가 할당되면 세그먼트 오류없이 해당 페이지의 모든 부분을 읽고 쓸 수 있습니다. (코드 페이지는 일반적으로 쓰기로부터 보호됩니다.)

malloc을 사용할 때 필요한 페이지가 있는지 확인합니다. 그러나 당신은 당신이 가지고있는 메모리에 접근 할 수 있고 당신이 좋아하는 방식으로 바꿀 수 있습니다.(그 정도를 알고 있다고 가정하면)

일반적으로이 방법은 유용 할뿐만 아니라 잘못된 방법으로 메모리에 액세스해도 세그먼테이션 오류가 보장되지 않는 이유를 설명하는 데 도움이됩니다.

주 : malloc은 작은 구조를 가지고 있습니다. 8 바이트, 블록 자체 앞에있는 각 할당 된 메모리 블록의 시작 부분에서이 경우 손상되면 mallocfree이 올바르게 작동하지 않습니다.

6

정의되지 않은 동작이 호출됩니다. 정의되지 않은 동작은 이름에서 알 수 있듯이 세그먼트 화 오류가 발생하도록 정의되지 않았습니다. 그 코드는 그 기억의 가치를 당신이주고있는 가치로 설정할 수 있고, 과제를 완전히 무시할 수도 있고, 우리가 아는 모든 것에 피자를 주문할 수도 있습니다.

+3

+1 피자 주문. 피자 좀 피워주세요. –

1

malloc은 메모리가 프로세스에 할당되는 방법의 일부일뿐입니다.

메모리는 전체 페이지에서 운영 체제에 의해 프로세스에 주어 지므로 4kB 또는 4MB (또는 기타 ...) 크기의 청크가 큽니다. 그런 다음 사용자 공간에서 프로세스가 좋아하는 방식으로 해당 페이지를 잘라낼 수 있습니다. 그래서 무엇 일어나고있는 것은 당신이 어딘가에 착륙하고 내기 할당 덩어리

에 해당 페이지를 분할 운영 체제

  • 에서

    • 요청 페이지 :

      malloc

      는이 개 역할을 제공 다른 페이지는 자신이 할당 한 덩어리가 아닌 소유하고있는 페이지입니다. 지금까지 OS가 걱정된다면 괜찮습니다.

  • 0

    소유하지 않은 메모리에 쓰기가 반드시 세그먼트 화 오류를 일으키는 것은 아닙니다.

    다른 포인터를 덮어 쓰면 나중에 세그먼트 오류가 발생하는 포인터에 액세스하려고합니다. 그래서 이러한 오류는 일반적으로 디버그하기가 어렵습니다.

    0

    이것은 고전적인 힙 손상 버그입니다. 그것은 크래시가있을 수도 있고 안할 수도 있습니다 - 얼마나 운이 좋은가에 달려 있습니다.

    치명적이지 않은 방식으로 가장 많이 사용되거나 손상 될 가능성이있는 힙 부분을 덮어 쓰고 있습니다.

    관련 문제