2011-03-08 2 views
1

아래 코드를 이해하는 데 도움이 필요합니다 ... alloc은 메모리를 할당하기 위해 오버로드 된 new 연산자에 의해 호출되는 함수입니다. ..새 메모리 오버로드 및 삭제 C++ 메모리 할당 추적

// get original block 
void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t); //? 

*static_cast<std::size_t*>(mem) = pAmount; //please explain? 

return static_cast<char*>(mem) + sizeof(std::size_t); //? 

및 코드는 다음과 같습니다 : 나는 문제가 특히 다음 캐스트를 이해하려고 노력 데

const std::size_t allocation_limit = 1073741824; // 1G 
    std::size_t totalAllocation = 0; 

    void* allocate(std::size_t pAmount) 
    { 
     // make sure we're within bounds 
     assert(totalAllocation + pAmount < allocation_limit); 

     // over allocate to store size 
     void* mem = std::malloc(pAmount + sizeof(std::size_t)); 
     if (!mem) 
      return 0; 

     // track amount, return remainder 
     totalAllocation += pAmount; 
     *static_cast<std::size_t*>(mem) = pAmount; 

     return static_cast<char*>(mem) + sizeof(std::size_t); 
    } 

    void deallocate(void* pMemory) 
    { 
     // get original block 
     void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t); 

     // track amount 
     std::size_t amount = *static_cast<std::size_t*>(mem); 
     totalAllocation -= pAmount; 

     // free 
     std::free(mem); 
    } 

답변

6

할당자는 크기를 추적 할당을 클라이언트 코드에 제공하는 블록과 함께 유지함으로써 pAmount 바이트의 블록을 요청하면 처음에 여분의 sizeof(size_t) 바이트를 할당하고 거기에 크기를 저장합니다. 이 크기를 얻으려면 malloc에서 size_t*으로 가져 오는 mem 포인터를 해석하고 (*static_cast<std::size_t*>(mem) = pAmount;)를 역 참조하십시오. 그런 다음 나머지 블록을 반환합니다.이 블록은 클라이언트가 사용할 수있는 부분이기 때문에 mem + sizeof(size_t)에서 시작합니다.

할당을 해제 할 때 정확한 포인터를 malloc에서 free으로 전달해야합니다. 이 포인터를 얻으려면 allocate 멤버 함수에서 추가 한 sizeof(size_t) 바이트를 뺍니다.

두 경우 모두 void 포인터에 포인터 연산이 허용되지 않으므로 char*으로 캐스트가 필요합니다.

+0

그래서 * static_cast <표준 :이 size_t *> (MEM) =이 될 수 pAmount size_t * ptr = static_cast (mem) ... 여기서 ptr은 할당 된 메모리의 시작을 가리키며 * ptr = pAmount; ? – maxpayne

+0

@maxpayne : 맞습니다. –

+0

allocate 함수에서 리턴 값 0과 리턴 NULL 사이에 차이가 있습니까? 값이 0 인 매크로는 null입니까? – maxpayne

0

메모리를 삭제할 때 (그리고 일부 진단을 제공 할 때) 얼마나 많은 메모리를 정리해야하는지 알기 위해 할당자는 여분의 할당 된 메모리에 크기를 저장합니다.

* static_cast (mem) = pAmount; //설명 해주십시오?

할당 된 메모리를 사용하고 할당 된 바이트 수를이 위치에 저장합니다. 캐스트는 저장을 위해 원시 메모리를 size_t으로 처리합니다.

return static_cast (mem) + sizeof (std :: size_t); //?

그러면 크기 바이트를지나 응용 프로그램에서 사용할 실제 메모리로 이동하여 해당 포인터를 반환합니다.

공극 * MEM = static_cast (pMemory) - 를 sizeof (표준 : size_t로); //?

이전에 사용자에게 반환 된 블록을 가져 와서 이전에 크기를 저장 한 "실제"할당 된 블록으로 되돌아갑니다. 수표를 발행하고 메모리를 회수해야합니다.

+0

할당 해제에 추가 정보가 필요하지 않습니다. 'free'는 그것을 처리합니다. –

0

void *는 크기가있는 유형이 아니기 때문에 적절한 오프셋을 얻으려면 캐스트가 필요합니다.

당신이

반환 static_cast (MEM) +를 sizeof (표준 : : size_t로)를 쓸 때;

오프셋 바이트가 추가되기 전에 포인터가 char *에 캐스트됩니다.

할당 해제시 뺄셈.

2

무효가 * (표준 : : size_t로 pAmount)를 할당

이 크기

|-size-|---- pAmount of memory-----| 

^
    | 

를 저장하는 메모리를 더한 공간 pAmount을 할당 "할당"포인터는 단지 크기 필드를 붙여 반환합니다.

void deallocate(void* pMemory) 

처음

|-size-|---- pAmount of memory-----| 

^ 
| 

과 무료로 다시 포인터를 이동합니다.

1)

std::size_t mySize = 0; 

void * men = & mySize; 

// same as: mySize = 42; 
*static_cast<std::size_t*>(mem) = 42; 

std::cout << mySize; 
// prints "42" 

2)

`return static_cast<char*>(mem) + sizeof(std::size_t); 
// casts void pointer mem to a char* so that you can do pointer arithmetic. 
// same as 

char *myPointer = (char*)mem; 

// increment myPointer by the size of size_t 
return myPointer + sizeof(std::size_t); 

3)

`void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t);` 
// mem points size of size_t before pMemory 
+0

간단한 예를 주셔서 감사합니다 ... – maxpayne