Clang error: pointer being freed was not allocated
Clang error: pointer being freed was not allocated
我写了这个链表的实现:
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 收到此消息:
proofs(13417,0x7fff7bb9f000) malloc: * error for object 0x7fe10b603170: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
Abort trap: 6
我该怎么做才能修复它?
明显的错误是这样的:
void concat(Linked_list<T> p_list)
您正在按值传递 Linked_list
。这意味着链表的临时副本被创建和销毁。由于析构函数删除了内存,因此它也删除了您正在复制的链表的内存。
由于您的 Linked_list
class 没有用户定义的赋值运算符或复制构造函数来处理指向动态分配内存的成员,因此无法安全地复制 class (如果你调试过,你应该看到调用了一个你意想不到的析构函数,那就是临时对象被销毁,从而破坏了原来的对象)。
为防止这种情况,要么按引用传递(不是值),
void concat(Linked_list<T>& p_list)
或提供适当的复制构造函数和赋值运算符。
见What is the rule of Three
我写了这个链表的实现:
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 收到此消息:
proofs(13417,0x7fff7bb9f000) malloc: * error for object 0x7fe10b603170: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug Abort trap: 6
我该怎么做才能修复它?
明显的错误是这样的:
void concat(Linked_list<T> p_list)
您正在按值传递 Linked_list
。这意味着链表的临时副本被创建和销毁。由于析构函数删除了内存,因此它也删除了您正在复制的链表的内存。
由于您的 Linked_list
class 没有用户定义的赋值运算符或复制构造函数来处理指向动态分配内存的成员,因此无法安全地复制 class (如果你调试过,你应该看到调用了一个你意想不到的析构函数,那就是临时对象被销毁,从而破坏了原来的对象)。
为防止这种情况,要么按引用传递(不是值),
void concat(Linked_list<T>& p_list)
或提供适当的复制构造函数和赋值运算符。
见What is the rule of Three