2017-04-08 16 views
3

노드가 정의된다이 프로그램은 8 페이지를 할당하지만 크기가 8 바이트 인 2048 개의 노드에만 맞을 수있는 이유는 무엇입니까? 다음

struct node{ 
     int value; 
     struct node *next; 
    }; 

sizeof(struct node)를 사용하여 I는 노드 (xv6 년) 8 바이트 것을 배운다. 그래서 일부 노드를 저장하기 위해 메모리 공간을 할당하기 위해 malloc을 사용합니다. xv6의 단일 페이지는 4096 바이트이고, 8 페이지가 있으면 4096 개의 노드를 저장할 수 있습니다. 그러나, 내가 무슨 그런 노드가, 내가 malloc 또 하나, 더 많은 페이지가 현재 프로세스에 할당되어 있다면, 그게 무슨 일이 일어나고 있지?

// Now display how many pages are allocated to the process 
    // Suppose there is a system call named memcount(), it is given by 
    // my professor, I wouldn't think there's any problem with that 
    // 
    memcount(); // which prints 3, meaning that initially, without 
       // allocaing anything, 3 pages = 12288 bytes of memory allocated 

    for(i = 0; i < 2048; ++i){ 
     struct node *nd = (struct node *)malloc(sizeof(struct node)); 
    } 

    memcount(); // which prints 11, so 8 more pages are allocated 

    // If we allocated 1 more node 
    struct node *nd = (struct node *)malloc(sizeof(struct node)); 
    memcount(); // which prints 19, another 8 pages are allocated 

내가 너무 혼란 스럽기 때문에 처음 8 페이지에 많은 공간이 남아 있지 않아야합니까? 단일 노드의 크기가 단지 8 바이트이기 때문에 프로세스에 더 많은 페이지가 할당되는 이유는 무엇입니까?

+5

'malloc (X)'는'X' 바이트 이상의 메모리를 사용합니다. 일부 메모리는 힙 제어 구조에 대해 은밀하게 할당됩니다. – DyZ

+0

일반적으로 소량의 메모리를 할당하면 실제로 지정한 용량보다 많은 용량을 예약 할 수 있습니다 (시스템이 할당 할 최소 크기 또는 할당 크기가 두 배가되는 등의 문제가있을 수 있음).또한 할당 된 블록의 세부 정보를 유지하기 위해 추가 오버 헤드가있을 수 있으며 요청한 부분 외부의 공간을 사용합니다. – Dmitri

+0

@ 드미트리, 감사합니다. 나는'malloc (n)'이'n' 바이트보다 조금 더 많은 것을 사용한다는 것을 이해한다. 그러나 그것은 약간 옳을 것이다. 어떻게 된거야? 나는 포스트를 편집했는데, 그것이 더 명확하게 설명한다고 생각한다. –

답변

1

질문에 이미 답변되었습니다 : 댓글 : malloc()은 메모리를 저장하는 데 약간의 공간이 필요합니다.

메모리 처리기는 힙을 하나의 큰 바이트 배열로 봅니다 (RAM은 대부분의 메모리 모델에서 하나의 큰 배열이기 때문에). (다른 메모리 모델이 있거나 memorymanager가 여분의 페이지에 데이터를 저장할 수도 있지만 간단하게하기 위해 이러한 경우는 무시합니다.)

예를 들어, 처음 4 바이트가 변수 (size_t, s0)의 다음 유효 바이트가 시작되고 다음 4 바이트가이 블록에 사용되는 포인터 (p0)입니다 (두 블록 사이의 블록이 해제 될 때 감지하기 위해 2 개의 변수가 필요합니다). 다음 블록은 또한 당신이 사용할 수있는이 헤더 후 (s1)

블록의 크기에 대한 블록 (다음의 다음) 및 변수 다음 데이터입니다에 대한 포인터 (p1), malloc() 반환 a를 가지고 이 헤더 뒤의 첫 번째 바이트를 가리키는 포인터. 변수 s0은 요청한 바이트 수를 저장합니다. 새로운 malloc() 후, 새로운 헤더는 첫 번째 블록 이후에 생성 될 것이며, P0는이 헤더를 가리 킵니다 : 당신이 2 개 블록, p1s1 헤더에 대한 변수를 ALLOC 후 다음

Address: 0x10 0x14 0x18 0x1B 0x20 0x24 0x28 ... 
Name:  p0  s0  value next p1  s1  value... 
Value:  0x20 8  ??  0x28 0  8  ?? 

상황입니다 두 번째 블록의 변수 nextvalue 만 사용할 수 있습니다. malloc()이 반송 된 포인터는 0x180x28입니다.

메모리 핸들러의 공간을 절반으로 사용하지 않으려면 한 단계에서 더 큰 배열을 할당 할 수 있습니다.

다음
struct Node_T 
    { 
    int values[512]; 
    size_t usedValues; 
    struct Node_T *next; 
    } 

당신이 memoryhandler의 오버 헤드를 포함하여 4 * 4 = 16 바이트 총 오버 헤드를 (필요하고, memoryhandler 필요 블록 당 8 바이트 헤더와 int, 포인터를 가정 한 것이며 :이 같은 struct을 사용할 수 있습니다 size_t은 4 바이트입니다). 그러나 다른 값 사이에서 값을 제거하거나 추가 할 때 여분의 복사 또는 오버 헤드가 필요합니다.