-4

std :: uint_8 포인터가 포함 된 클래스가 있으며 소멸자를 호출하여 할당 된 메모리를 삭제해야합니다. 내가 겪고있는 문제는 컴파일러 오류가 발생하고 메모리가 할당되지 않았다고 나와 있지만 기본 생성자에 할당 된 것입니다.소멸자가 할당 된 메모리를 삭제하지 않음

BigInteger::BigInteger() { 
    unsigned char aArray [4]; 
    aArray[0] = 0; 
    m_number = new unsigned char[4] 
    m_number = aArray; 
    m_digitCount = 0; 
    m_sizeReserved = 4; 
} 

여기 내 소멸자의 :

BigInteger::~BigInteger() { 
    delete [] m_number; 
} 
+10

'm_number = aArray;'무엇을 기대합니까? – tkausl

+0

'm_number'를'new'와 함께 할당합니다. 그러나 다음 줄에 그것을 다시 로컬 배열에 할당합니다. –

+0

나중에 메모리 누수가 아니라 정의되지 않은 동작입니다. – NathanOliver

답변

2

여기서 스택에 4 개의 요소 배열을 만듭니다. 생성자가 끝나면 범위를 벗어납니다.

m_number = new unsigned char[4] 이제 힙에 4 개의 요소를 만듭니다. 당신은 메모리를 할당하고 그것을 정리하는 책임을지게 될 것입니다. 문제는 아닙니다. 소멸자에서 그렇게합니다.

m_number = aArray; 이제 m_number이 가리키는 내용을 변경하여 할당 한 메모리에 대한 포인터가 손실됩니다. 이제 누수가 생겼어.

더 이상 소유하지 않은 메모리에 액세스하고 있으므로이 생성자 외부에서 m_number을 사용하면 정의되지 않은 동작이됩니다.

delete [] m_number; 이제 소유하지 않은 메모리를 삭제하고 있습니다. UB.

m_number을 재 할당하지 마십시오. 이러한 문제가 발생하지 않습니다. 더 나아가서는 std::vector을 사용하고 이러한 수동 메모리 관리 문제가 없어지는 것을 지켜보십시오.

0

당신은 메모리의 고전적인 시나리오 누출이 여기 내 기본 생성자입니다.

  1. 할당 메모리 (m_number = new unsigned char[4])
  2. 오버라이드가 할당 된 메모리를 가리키는 포인터 (m_number = aArray)
  3. 마십시오 당신으로 할당 된 메모리를 삭제하지 않습니다 더 이상 : 본질적으로 무슨 일을하면 다음과 같은입니다 어디 있는지 알고 - 당신은 (그것을 덮어있어)
1

그 라인이 포인터를 잃은

m_number = aArray; 

은 로컬 변수의 주소를 m_number에 할당합니다.

해당 주소는 delete [] m_number;과 함께 사용할 수 없으며 new unsigned char[4]으로 할당 된 메모리 주소는 해당 할당 후에 무시되고 손실됩니다.