我写了这个链接列表的实现:
template<typename T> // implementation: Linked_list
class Linked_list {
private:
Node<T>* head;
Node<T>* tail;
Node<T>* current;
int size;
void init()
{
head = tail = current = new Node<T>();
size = 0;
}
Node<T>* search_previous()
{
if (current == head) {
return nullptr;
}
Node<T>* previous_node = head;
while (previous_node->next != current) {
previous_node = previous_node->next;
}
return previous_node;
}
public:
Linked_list()
{
init();
}
void clear()
{
while (head != nullptr) {
current = head;
head = head->next;
delete current;
}
init();
}
~Linked_list()
{
clear();
delete head;
}
void append(T p_element)
{
tail->next = new Node<T>(p_element);
tail = tail->next;
++size;
}
void insert(T p_element)
{
current->next = new Node<T>(p_element, current->next);
if (current == tail) {
tail = tail->next;
}
++size;
}
T remove()
{
if (current->next == nullptr) {
throw std::runtime_error("No element to remove");
}
T removed_element = current->next->element;
Node<T>* temporary_pointer = current->next;
current->next = current->next->next;
if (temporary_pointer == tail) {
tail = current;
}
delete temporary_pointer;
--size;
return removed_element;
}
T get_element()
{
if (current->next == nullptr) {
throw std::runtime_error("No element to get");
}
return current->next->element;
}
void go_to_start()
{
current = head;
}
void go_to_end()
{
current = tail;
}
void go_to_pos(int p_pos)
{
if ((p_pos < 0) || (p_pos >= size)) {
throw std::runtime_error("Index out of bounds");
}
current = head;
for (int index = 0; index < p_pos; ++index) {
current = current->next;
}
}
void next()
{
if (current != tail) {
current = current->next;
}
else {
throw std::runtime_error("There's no next positition");
}
}
void previous()
{
if (current != head) {
current = search_previous();
}
else {
throw std::runtime_error("There's no previous positition");
}
}
int get_pos()
{
int pos = 0;
Node<T>* temporary_pointer = head;
while (temporary_pointer != current) {
temporary_pointer = temporary_pointer->next;
++pos;
}
return pos;
}
int get_size()
{
return size;
}
void concat(Linked_list<T> p_list)
{
for (p_list.go_to_start(); p_list.get_pos() < p_list.get_size(); p_list.next()) {
append(p_list.get_element());
}
}
};
这是节点:
template<typename T>
class Node {
public:
T element;
Node<T>* next;
Node(T p_element, Node<T>* p_next = nullptr)
{
element = p_element;
next = p_next;
}
Node(Node<T>* p_next = nullptr)
{
next = p_next;
}
};
我遇到的问题是,当我尝试使用方法concat
时,我从Clang那里收到了这条消息:
证明(13417,0x7fff7bb9f000)malloc: *对象0x7fe10b603170的错误:未释放指针被释放 * 在malloc_error_break中设置断点以进行调试 中止陷阱:6
我可以做些什么来解决它?
答案 0 :(得分:1)
明显的错误是:
void concat(Linked_list<T> p_list)
您按值传递Linked_list
。这意味着创建并销毁链表的临时副本。由于析构函数删除了内存,因此它也会删除您正在复制的链表的内存。
由于您的Linked_list
类没有用户定义的赋值运算符或复制构造函数来处理指向动态分配的内存的成员,因此无法安全地复制该类(如果您已调试,则应该看到一个析构函数被调用,你没想到,这就是临时被破坏,从而破坏了原始对象。)
为了防止这种情况,要么通过引用传递(而不是值),
void concat(Linked_list<T>& p_list)
或提供适当的复制构造函数和赋值运算符。