Загадочная ошибка сегментации на разрушение
В песне "God Writed in LISP Code "говорится, что" только Бог может сделать дерево " на языке Си (или Си++); я начал верить.
У меня есть начало класса дерева, но мой класс segfaults на разрушение говорит, что ошибка - это моя очередь free_spaces
, хотя я не понимаю, почему. Кроме того, случайные ошибки, кажется, скрываются здесь и там.
Я никогда раньше не использовал такие шаблоны, так что, возможно, там происходит какое-то скрытое злоупотребление.
Любая помощь была бы оцененный.
Заголовок.h
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
template <class T>
class node {
public:
int leftChild,parent;
bool empty;
T data;
node() : leftChild(-1), parent(-1), empty(true) {}
};
template <class T>
class AvlTree {
private:
vector< node<T> > nodes;
queue<int> free_spaces;
int root;
int newnode(int parent){
int index=nodes.size();
nodes.push_back(node<T>());
nodes[index].parent=parent;
return index;
}
public:
AvlTree(){
nodes.push_back(node<T>());
root=0;
}
void grow(){
nodes[root].leftChild=newnode(root);
}
};
Главное.h
#include "header.h"
int main(){
AvlTree<int> bob;
bob.grow();
cerr<<"Made it to end."<<endl;
}
2 ответа:
Проблема заключается в следующей строке кода:
nodes[parent].leftChild=newnode(parent);
Просто заменив его этим исправляет его:
Это в конечном счете сводится к порядку оценки. Дело в том, что функцияint left = newnode(parent); nodes[parent].left = left;
newnode()
изменяет длину вектора. Это может заставитьstd::vector<>
перераспределить память, чтобы расти (т. е. если текущей емкости недостаточно). Если вы нажмете на этот случай, выражениеnodes[parent].left
в левой части, если оно вычисляется до вызоваnewnode()
, будет указывать на потенциально недопустимую память местоположение.
Valgrind показывает эту ошибку:
Этого должно быть достаточно, чтобы вы нашли ошибку.==23995== Invalid write of size 4 ==23995== at 0x400F68: AvlTree<int>::grow() (/tmp/header.h:39) ==23995== by 0x400BC6: main (/tmp/t.cc:5) ==23995== Address 0x5967770 is 0 bytes inside a block of size 16 free'd ==23995== at 0x4C29DFD: operator delete(void*) (/coregrind/m_replacemalloc/vg_replace_malloc.c:456) ==23995== by 0x401FC5: __gnu_cxx::new_allocator<node<int> >::deallocate(node<int>*, unsigned long) (/usr/include/c++/4.4/ext/new_allocator.h:95) ==23995== by 0x40187B: std::_Vector_base<node<int>, std::allocator<node<int> > >::_M_deallocate(node<int>*, unsigned long) (/usr/include/c++/4.4/bits/stl_vector.h:146) ==23995== by 0x401743: std::vector<node<int>, std::allocator<node<int> > >::_M_insert_aux(__gnu_cxx::__normal_iterator<node<int>*, std::vector<node<int>, std::allocator<node<int> > > >, node<int> const&) (/usr/include/c++/4.4/bits/vector.tcc:361) ==23995== by 0x40106B: std::vector<node<int>, std::allocator<node<int> > >::push_back(node<int> const&) (/usr/include/c++/4.4/bits/stl_vector.h:741) ==23995== by 0x40131A: AvlTree<int>::newnode(int) (/tmp/header.h:24) ==23995== by 0x400F67: AvlTree<int>::grow() (/tmp/header.h:39) ==23995== by 0x400BC6: main (/tmp/t.cc:5)