2017-11-29 14 views
3

개념에 익숙해지기 위해 간단한 메모리 관리자를 만들려고합니다. 전역 전역에 대한 재정의를 새로 제공하고 삭제하고 일부 객체를 생성하는 데 방해가되기 시작했습니다. 단일 동적 문자열 할당에 대해 새로운 것을 두 번 치는 것처럼 보였습니다. 처음으로 new에 도달하면 문자열 생성자가 호출되기 전에 이상하게도 두 할당 중 큰 값을 얻습니다. 두 번째 할당이 발생하면 std :: string (basic_string) 생성자에서 호출이 발생합니다.동적으로 std :: string을 만들 때 두 개의 'new'호출이 발생했습니다.

저는 두 가지 새로운 것이 무엇인지 알고 싶습니다. 특히, 새로운 개념의 모든 것이 자체 할당 헤더를 생성하고 간단한 메모리 관리자를 사용하면 오버 헤드가 발생한다는 학문적 인 호기심이 생기기 때문에이 컨텍스트에서주의를 기울입니다.

관련 코드 :이

STARTING MEMORY MANAGEMENT TESTING 
******************* Creating DATA ******************* 
[New] 28 
[New] 8 
[Delete] 00D88C18 
[Delete] 00D88BC8 
******************* Creating LORE ******************* 
[New] 28 
[New] 8 
[Delete] 00D88C18 
[Delete] 00D88BC8 

사업자가 새로운 실행하고

void * operator new(std::size_t size, MemoryManagement::Heap* heap) 
{ 
    assert(heap != nullptr); 
    assert(size > 0); 
    return heap->Allocate(size); 
} 

void * operator new(std::size_t size) 
{ 
    printf("[New] %i \n", size); 
    return operator new (size, MemoryManagement::HeapFactory::GetDefaultHeap()); 
} 

void operator delete (void * memoryLocation) 
{ 
    if (memoryLocation != NULL) 
    { 
     printf("[Delete] %p \n", memoryLocation); 
     MemoryManagement::Heap::Deallocate(memoryLocation); 
    } 
} 

을 삭제

class DumbDataType 
{ 
    std::string m_name; 
}; 

int main() 
{ 
    printf("STARTING MEMORY MANAGEMENT TESTING \n"); 

    printf("******************* Creating DATA ******************* \n"); 
    std::string* data = new std::string(); 
    delete data; 

    printf("******************* Creating LORE ******************* \n"); 
    DumbDataType * lore = new DumbDataType(); 
    delete lore; 

    getchar(); 
} 

출력은 'GetDefaultHeap'메소드는 첫 도착 엘멘 t는 정적으로 할당 된 힙 배열입니다.

크기와 헤더에 충분한 메모리를 할당하고 헤더를 오프셋 한 다음 적절한 시작 주소를 반환합니다. 에 대한 하나 할당 해제는

+4

당신이 그것을 할당 있는지 확인하기 위해'표준 : string'의 생성자 봤어입니까? –

+0

@SebastianRedl 그래, 그랬어. 제가 말했듯이, 첫 번째 새로운 것은 생성자에 들어가기 전에 발생합니다. 두 번째 생성자는 생성자가 실행되는 과정에서 발생합니다. – Vidrohi

+0

제 말은 소스 코드를 살펴 보았습니까? 첫 번째'new'는 여러분이 작성한 코드에서 작성한 것입니다. 생성자 안에 아마 두 번째'new '가있을 것입니다 (아마도 할당 자 뒤에 숨겨져 있습니다). 이것은 소스를 읽음으로써 간단하게 발견 할 수 있습니다. –

답변

6
new std::string() 

이 두 할당이 필요합니다 (그것은 너무 많은 코드처럼 보였다가 도와 주면 나는이 방법을 게시 할 수 있습니다)가 얻고 메모리 가 해제 메모리 주소에서 오프셋 헤더를 뺍니다 std::string 개체이고, 다른 하나는 기본 메모리 버퍼입니다.

당신이

std::string s; 

을 썼다면 당신이 한 번 new를 호출 볼 수 있습니다.

+1

흥미 롭습니다. 장소, 객체 및 버퍼 할당에 대해 더 자세히 읽을 수 있습니까? – Vidrohi

+0

'std :: string s;' 그것은 스택 건설 것인가? 그것은 문자열 객체와 버퍼를 하나의 인접한 할당에 넣는 것입니까? – Vidrohi

+0

@Vidrohi 문자열 객체 자체를 스택에 넣을 것입니다 (버퍼에 대한 포인터, 버퍼 크기 및 버퍼에있는 데이터 바이트 수).하지만 거의 확실하게 왜냐하면 크기를 조정하거나 해제 할 수 없으므로'std :: string' 코드 전체에 걸쳐 모든 종류의 특별한 경우가 필요하기 때문입니다. –

1

@YSC pointed out으로 여기에 new에 대한 두 건의 호출이 있습니다. 첫 번째 newstd::string 개체를 할당하고 그에 대한 포인터를 반환하지만 std::string 개체도 그 안에 포인터가 있으며 생성 될 때 new도 호출합니다.

class DumberDataType 
{ 
public: 
    DumberDataType() 
    { 
     i = new int; 
    } 

private: 
    int * i; 

}; 

class DumbDataType 
{ 
    DumberDataType ddt; 
}; 

int main() 
{ 
    printf("STARTING MEMORY MANAGEMENT TESTING \n"); 

    printf("******************* Creating DATA ******************* \n"); 
    DumbDataType* data = new DumbDataType(); 

    getchar(); 
} 

이 코드의 출력은

STARTING MEMORY MANAGEMENT TESTING 
******************* Creating DATA ******************* 
[New] 4 
[New] 4