2017-02-18 10 views
-1

나는 벽돌 벽에 머리를 두들겨 맞고있는 것처럼 느껴진다.내 프로그램에서 메모리 누수가 발생했습니다. 소멸자가 부르지 않았나요?

소멸자가 실제로 호출되는 것은 확실하지 않습니다. priority_queue를 사용하여 많은 노드를 보유하고 있습니다. 각 노드에는 구조체의 2D 배열 인 멤버 인 m_grid가 있습니다. 이 그리드는 내 프로그램에서 명시 적으로 사용하는 유일한 포인터를 나타냅니다.

웬일인지, 나는 많은 누설을 얻고있다. 너 좀 도와 줄 수있어?

grid::~grid() 
{ 
    for (int i = 0; i < m_width; i++) 
    { 
    delete[] m_grid[i]; 
    m_grid[i] = NULL; 
    } 

    delete[] m_grid; 
    m_grid = NULL; 
} 

할당 연산자 :

grid& grid::operator=(const grid& g) 
{ 
    m_x_rad = g.m_x_rad; 
    m_y_rad = g.m_y_rad; 
    m_width = g.m_width; 
    m_height = g.m_height; 
    m_orientation = g.m_orientation; 

    if (m_width != 0) 
    m_grid = new cell* [m_width]; 

    // from left to right 
    for (int i = 0; i < m_width; i++) 
    { 
    m_grid[i] = new cell [m_height]; 

    // from top to bottom 
    for (int j = 0; j < m_height; j++) 
    { 
     m_grid[i][j].m_occupied = g.m_grid[i][j].m_occupied; 
     m_grid[i][j].m_rad = g.m_grid[i][j].m_rad; 
    } 
    } 

    return *this; 
} 

할당 연산자는 유사한로 예상이다

여기 소멸자입니다. 마지막으로, 여기에 Valgrind의 출력의 비트 (이 많은,하지만 모든 문제 그리드 ::에는 setSize() 또는 그리드 :: 연산자 =.

==13329== 200 (40 direct, 160 indirect) bytes in 1 blocks are definitely lost in loss record 25 of 166 
==13329== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==13329== by 0x4020C1: grid::operator=(grid const&) (grid.cpp:192) 
==13329== by 0x40A02E: node::operator=(node const&) (node.cpp:129) 
==13329== by 0x4075A6: __push_heap<__gnu_cxx::__normal_iterator<node*, std::vector<node> >, long int, node, __gnu_cxx::__ops::_Iter_comp_val<std::greater<node> > > (stl_heap.h:135) 
==13329== by 0x4075A6: push_heap<__gnu_cxx::__normal_iterator<node*, std::vector<node> >, std::greater<node> > (stl_heap.h:199) 
==13329== by 0x4075A6: push (stl_queue.h:502) 
==13329== by 0x4075A6: aStarGraphSearch(basic_map const&, node&, std::unordered_map<int, basic_node, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, basic_node> > >&, std::priority_queue<node, std::vector<node, std::allocator<node> >, std::greater<node> >&) (main_functions.cpp:216) 
==13329== by 0x4088ED: search(int) (main_functions.cpp:706) 
==13329== by 0x401AAA: main (main.cpp:13) 

정말 여기 사투를 벌인거야가. 내가하지 않았다이다 내가 대신 우선 순위 큐의 스택을 사용했을 때 이러한 문제는. 당신의 할당 연산자에 어떤 도움을

+2

[mcve]가 없으면 신뢰할 수있는 답변이 없지만 복사 생성자가 동적으로 할당 된 기존 클래스 멤버를 파기하지 못해 메모리 누수가 발생한다는 것은 명백합니다. –

+1

'operator ='는 이전 메모리를 삭제하지 않고 메모리를 할당하고 있습니다. 이것은 의도적입니까? –

+0

허용 된 경우 그리드를 캡처하려면'cell ** '대신'std :: vector >'을 사용하십시오. –

답변

1

당신은 m_grid을 삭제하지 마십시오. 감사합니다 (그리고 배열이 포함되어 있습니다).

+0

'm_grid '를 삭제하면 나중에 더 이상 그리드에 액세스 할 수 없습니다 ... 맞습니까? – hockeysaint

+0

@hockeysaint 맞습니다. 그러나 삭제하지 않으면 메모리 누수가 발생합니다. – emlai

+0

오, 나는 오해했다. 내가 틀렸다면 고쳐주세요,하지만'm_grid'를 가리키는 것은'm_grid'가 가리키고있는 것을 버립니다. 새로 만든'm_grid' 파일을 삭제해야한다고 생각했습니다. – hockeysaint

0

호출을 할당 연산자 아무튼에 자동적으로 소멸자가 먼저 호출됩니다. 객체를 소유하고있는 메모리를 정리해야합니다. 그것을 새로운 기억으로 배치하십시오.

과제가 새 객체를 만들지 않습니다. 이미 가지고있는 객체를 수정합니다.

+0

물론,'node top_node = frontier.top();'(프론티어가 내 큐인 곳)와 같이'top_node'는'frontier.top()'의 정확한 복사본으로 이해해야합니다. – hockeysaint

+0

@hockeysaint : 대입 연산자를 호출하지 않습니다. 그것은 초기화가 아니라 과제입니다. –