【发布时间】:2014-08-29 01:48:15
【问题描述】:
我正在尝试编写标准容器 std::list 的极简版本,作为 C++ 练习。但是,我在内存管理方面遇到了困难,因为我是 C++ 新手,并且来自 python/java,我们不必担心太多。代码如下:
#include <memory>
#include <cstddef>
#include <iostream>
template <typename T> class List {
public:
typedef std::size_t size_type;
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
template <typename U> class Node {
public:
Node() {
data = NULL;
init();
}
Node(const U val) {
data = new U(val);
init();
}
void init() {
prev = NULL;
next = NULL;
}
~Node() {
if (data != NULL)
delete data;
if (prev != NULL)
delete prev;
if (next != NULL)
delete next;
}
U* data;
Node* prev;
Node* next;
};
class iterator {
public:
iterator() {
n = new Node<T>();
}
iterator(const T val) {
n = new Node<T>(val);
}
iterator(Node<T>* nodeptr) {
n = nodeptr;
}
~iterator() {
delete n;
}
iterator operator++() {
n = n->next;
}
iterator operator--() {
n = n->prev;
}
T& operator*() {
return *(n->data);
}
bool operator==(iterator other) {
return (this->n == other.n);
}
Node<T>* n;
};
List() {
_begin = new iterator();
_end = new iterator(begin.n);
}
List(size_type n, T val) {
init(val);
}
~List() {
delete _begin;
delete _end;
}
void init(T val) {
_begin = new iterator(val);
Node<T>* nextNode = new Node<T>();
_begin->n->next = nextNode;
nextNode->prev = _begin->n;
_end = new iterator(nextNode);
}
void push_back(T val) {
if(_begin == _end) {
delete _begin;
delete _end;
init(val);
}
else {
Node<T>* endNode = _end->n;
Node<T>* lastNode = endNode->prev;
Node<T>* append = new Node<T>(val);
lastNode->next = append;
append->next = endNode;
append->prev = lastNode;
endNode->prev = append;
}
}
iterator begin() {return *_begin;}
iterator end() {return *_end;}
private:
iterator* _begin;
iterator* _end;
};
int main() {
List<int> derp= List<int>(3,3);
List<int>::iterator i = derp.begin();
std::cout << *i;
derp.push_back(4);
std::cout << *i;
}
当我运行代码时,我得到以下输出:
a.out(814) malloc: *** error for object 0x7fbab0403a70: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
33Abort trap: 6
我使用GNU调试器按预期设置断点,得到如下结果:
(gdb) break malloc_error_break
Function "malloc_error_break" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (malloc_error_break) pending.
(gdb) run
Starting program: /Users/samadwara/Projects/C++/a.out
Reading symbols for shared libraries ++.............................. done
Breakpoint 1 at 0x7fff90721588
Pending breakpoint 1 - "malloc_error_break" resolved
a.out(835) malloc: *** error for object 0x100103a90: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Breakpoint 1, 0x00007fff90721588 in malloc_error_break ()
(gdb) backtrace
#0 0x00007fff90721588 in malloc_error_break ()
#1 0x00007fff90722942 in free ()
#2 0x0000000100001864 in List<int>::Node<int>::~Node (this=0x100103a70) at list2.cpp:30
#3 0x0000000100001894 in List<int>::Node<int>::~Node (this=0x100103ad0) at list2.cpp:32
#4 0x00000001000018d0 in List<int>::Node<int>::~Node (this=0x100103a70) at list2.cpp:34
#5 0x000000010000190f in List<int>::iterator::~iterator (this=0x7fff5fbff930) at list2.cpp:55
#6 0x00000001000012ae in main () at list2.cpp:117
(gdb) frame 2
#2 0x0000000100001864 in List<int>::Node<int>::~Node (this=0x100103a70) at list2.cpp:30
warning: Source file is more recent than executable.
30 delete data;
(gdb) l
25 next = NULL;
26 }
27
28 ~Node() {
29 if (data != NULL)
30 delete data;
31 if (prev != NULL)
32 delete prev;
33 if (next != NULL)
34 delete next;
我发现问题出在删除数据上,但据我了解,数据总是用 new 初始化,所以我看不到问题所在。任何建议,即使是在代码的其他方面,都值得赞赏。
【问题讨论】:
-
delete NULL是无操作 BTW,请使用nullptr。此外,您没有调试最新的源代码。最后,节点的析构函数也不应该释放其兄弟节点。当它们破坏时会发生什么? -
I am trying to write an minimalist version of the standard container std::list, as a C++ exercise这就像一个初学钢琴的学生说“我正在尝试演奏贝多芬钢琴协奏曲的极简版本”。
标签: c++ debugging pointers memory-management gdb