2013-03-14 3 views
4

이 코드가 여러 메모리 누수를 일으키거나 올바르게 정리 될지 궁금했습니다.C++, for 루프에 공간을 할당 할 때 메모리 누출 가능성 확인

분명히 코드는 아무 것도하지 않지만 내 시나리오를 설명하는 데 도움이됩니다. 메모리를 10 번 할당하고 있습니까? 그리고 포인터를 삭제하면 9 명의 고아를 떠날 수 있습니까? 아니면 할당 된 같은 공간을 재사용하고 고아를 올바르게 제거합니까? 미리 감사드립니다.

+0

Valgrind를 사용하여 프로그램을 실행하여 메모리 누수가 있는지 확인할 수 있습니다. – taocp

+1

10 개의 항목, 1 개의 삭제, 9 개의 고아. – enhzflep

+0

당신은 전자를하고 있습니다. 마지막 할당 만 제대로 정리됩니다. 나머지 9 개의 개체는 고아가됩니다. – OldProgrammer

답변

6

예, 메모리 누수입니다. 당신이 할 경우 :

newNode = new Node(); 

당신은 그것을 삭제하기 위해 메모리에 이전에 지적을 주소로하여 방법을 놓치고 효과, 메모리를 새로 할당 가리 키도록 포인터를 재정의합니다.

따라서 루프를 떠날 때 newNode 포인터는 마지막으로 할당 된 (1/10) 메모리/Node을 가리 킵니다. delete newNode 때 그 메모리 만 삭제됩니다. 더 이상 다른 사람에게 delete 할 수있는 방법이 없습니다. 다우 왕는 지적

, 당신은 (C++ 11 예에서 unique_ptr 또는 shared_ptr) 스마트 포인터의 일부 양식을 사용할 수 있습니다. 이러한 스마트 포인터는 기본적으로 이러한 종류의 누출을 방지하는 추가 의미 체계가있는 일반 포인터 주위의 래퍼입니다. 이 중 하나를 사용하면 메모리/객체가 범위를 벗어 났을 때 (이 경우에는 for 루프의 현재 반복이 끝날 때) 메모리/객체가 자동으로 할당이 해제됩니다.

그러나이 경우 귀하의 상황을 해결할 수 있다고 생각하지 않습니다. 나는 당신이 그들을 창조하자마자 당신이 delete 10의 목표에 원한 ㄴ다는 것을 의심한다. 오히려 std::vector과 같은 컨테이너에 이러한 객체를 저장하거나 할당 된 각 인스턴스를 가리키는 포인터의 배열이 있어야합니다. 그렇게하면 주위에 물건을 갖게 될 것입니다. (내가 생각하기에 당신이 원하는 것입니다. 당신이 그것들을 전혀 구성하지 않기 때문에) 나중에 그것을 제거 할 수있는 방법이 있습니다.

+0

정확히, @ user1535978, 이런 식으로 일을하지 말고, 더 똑똑한 포인터를 사용하여 할당 된 메모리를 유지하십시오. –

+0

한꺼번에 고맙습니다. 마지막으로 사용한 후에 포인터를 삭제할 수있는 포인터 배열을 사용했습니다. 도움에 감사드립니다. :) – Xav

3

예, 코드가 메모리를 누설합니다. 행동에 대한 첫 번째 추측은 정확합니다. 이 코드

Node *newNode; 

for (int i = 0; i < 10; i++) 
{ 
    newNode = new Node(); // allocate memory 10 times in a loop... 
} 

delete newNode;   // ... but free the memory only once! 

메모리 10 번합니다 (for 루프 내부 new 연산자)를 할당하고 있지만, 그 개체의 하나 사용하는 메모리 (아래에서 delete 연산자)를 해제. 당연히 나머지 9 개의 객체는 고아가됩니다. 소비하는 메모리는 여전히 할당되어 있지만 이제는 자유롭게 액세스 할 수있는 방법이 없습니다. 그것은 물론 메모리 누수의 정의입니다. 반대로

, new 각 호출 delete 한 통화가 있으므로

Node *newNode; 

for (int i = 0; i < 10; i++) 
{ 
    newNode = new Node(); // allocate memory 10 times in a loop 
    delete newNode;   // ... and free the memory each time 
} 

가 메모리를 누설하지 않는 코드. 그것이 당신이 염두에 두어야 할 큰 규칙입니다 : 에 대한 각각의 호출을 일치시키지 않으면 delete에 대한 호출과 일치하지 않으면 메모리 누수가이됩니다.

또는 아마도 C++로 작업 할 때 더 좋은 규칙은 처음에는 원시 포인터를 사용하지 않을 것입니다. C++ 표준 라이브러리는 포인터에 대한 RAII 관용구를 구현하는 훌륭한 래퍼 클래스 몇 개를 제공합니다.이 클래스는 적절하게 파괴되고 그에 따라 소비되는 메모리가 해제되도록 지정합니다. 연구를 favorite C++ book 또는 Wikipedia에서 시작하십시오.

+0

앞으로는 원시 포인터를 사용하지 않을 것이지만,이 교수는 교수가이 과제에서 기대하는 바를 벗어납니다. 도와 주셔서 감사합니다. :) – Xav

+0

for 루프에 선언 된 변수를 삭제해야합니까? 나는 그것들이 닫는 대괄호에서 자동으로 삭제되는 줄 알았다. – CodyBugstein