2012-11-07 4 views
1

두 코드의 차이점은 무엇입니까? 첫 번째 경우에 메모리 누수가 있습니까? 그래서 books 어레이로서 할당된다소멸자 문제

더 소멸자

class Library 
{ 
private: 
    Book books[50]; 
    int index; 
public: 
    Library() 
    { 

     index=0; 
    } 
}; 

정의하거나 소멸 상기 제 2 하나

delete[] books; 

이어야

class Library 
{ 
private: 
    Book *books; 
    int index; 
public: 
    Library() 
    { 
     books=new Book[50]; 
     index=0; 
    } 
    ~Library() 
    { 
     delete books; 
    } 
}; 
+0

두 번째 UB 있습니다. 첫 번째 메모리 누수가 없습니다. 두 번째 규칙은 3/5의 규칙을 도입합니다. – chris

+0

나는 초보자이며, UB가 무엇을 의미하는지, 규칙 3/5인지 모르겠다. – laura

+0

"규칙 3+ C++"은 쉽게 검색 될 수있다. UB는 "정의되지 않은 동작"을 의미한다. 당신이하는 일에 대한 응답으로 집을 폭파시키는 것은 표준을 준수 할 것입니다. – Yakk

답변

3
delete books; 

정의 엠 배열로 삭제해야합니다. 첫 번째 버전에는 메모리 누수가 없습니다.

차이점은 첫 번째 경우에 books의 메모리는 Library의 각 인스턴스에 대한 할당 내에 포함되며 두 번째 경우에는 힙을 사용하여 별도로 할당된다는 점입니다.

1

첫째로, 두 번째 코드이어야

~Library() { 
    delete[] books; 
} 

newdelete가 일치해야 new[]delete[]는 매칭되어야한다.

첫 번째 코드에서 Library의 모든 인스턴스는 Book의 50 개의 인스턴스를 포함합니다. Library을 복사하면 50 개의 인스턴스가 복사됩니다. 메모리 누수가 없습니다.

두 번째 코드에서 Library의 인스턴스에는 해당 도서에 대한 포인터 만 포함됩니다. 인스턴스 복사 (기본 복사 생성자없이)는 포인터 만 복사합니다. 원본과 복사본은 50 권의 책을 공유하며, 두 번째로 삭제 된 사람은 이미 삭제 된 메모리에 delete을 발급합니다. 이것은 오류입니다.

+0

@Benjamin이 편집 해 주셔서 감사합니다. 생각보다 빨리 입력하고있었습니다 ... – Angew

1
~Library() 
{ 
    delete[] books; 
} 

이 적절한 해결책입니다. 코드에서 무료로 발생할 수있는 문제는 고려해야 수있다 :

1) 두 번째 경우에 초기화 목록

를 사용

2) 당신이 정말로 포인터를 어떻게해야합니까? 로컬 객체가 충분하지 않습니까? (귀하의 책이 스택 크기를 초과하지 않는다고 생각합니다). 작성한 코드를 처음부터 살펴보고 끝 부분에서 삭제하십시오. 스택이 더 빠르고 안전하다는 것을 기억하십시오.

또한 valgrind에 대해 잘 알고 있어야합니다. 정말 유용한 도구입니다. cppcheck가 도움이되는지 확인하십시오. "sudo apt-get install cppcheck"우분투에서.