我正在实现一个双向链表,当我尝试访问一个名为成员指针所指向的对象的成员时,我得到了一个段错误。我的链表由节点组成,节点有一个值和下一个和前一个指针
String(这是以前项目的基本实现):
class String{
public:
int len;
char *str;
String()
:len(0), str(nullptr){}
String(char const* S)
:len(strlen(S)), str(new char[len +1]){
assert(S != 0);
strcpy(str, S);
}
~String(){
delete[]str;
}
};
节点(我知道这不会实现'三巨头',我宁愿将这个课程保持在最低限度):
#include <initializer_list>
template<typename T>
struct Node{
T value;
Node* next;
Node* prev;
Node() = default;
Node(T t, Node* n, Node* p)
:value(t), next(n), prev(p){}
Node & operator=(const Node & N){
value = N.value;
next = N.next;
prev = N.prev;
return *this;
}
};
双重链表:
template<typename T>
struct List
{
List(std::initializer_list<T>);
Node<T>* head;
Node<T>* tail;
List()
:head(nullptr), tail(nullptr){}
//copy constructor
List(const List<T> & l){
Node<T>* p = l.head;
head = p;
Node<T>* past;
while(p){
Node<T>* q = new Node<T>;
*q = *p;
if(head == p){
head = q;
}else{
past->next = q;
q->prev = past;
}
past = q;
p = q->next;
}
tail = past;
}
//copy assignment
List & operator=(const List & L){
List temp = L;
swap (*this, temp);
return *this;
}
Node<T>* getHead()const{
return head;
}
Node<T>* getTail()const{
return tail;
}
void swap(List a, List b){
Node<T>* temp1 = a.getHead();
Node<T>* temp2 = a.getTail();
a.head = b.getHead();
a.tail = b.tail;
b.head = temp1;
b.tail = temp2;
}
void push_back(T t){
Node<T>* p = new Node<T>(t, nullptr, tail);
if(tail){
tail->next = p; //Segfault occurs here
}else{
head = p;
}
tail = p;
}
int compare(const List<T> & b)const{
Node<T>* temp1 = this->head;
Node<T>* temp2 = b.head;
while (temp1 != this->tail && temp2 != b.tail) {
if (temp1->value < temp2->value)
return -1;
if (temp2->value < temp1->value)
return 1;
}
if (temp1 == this->tail) {
if (temp2 != this->tail)
return -1; // [first1, last1) is a prefix of [first2, last2)
else
return 0; // [first1, last1) and [first2, last2) are equivalent
}
else {
return 1; // [first2, last1) is a prefix of [first1, last1)
}
}
size_t size()const{
size_t n = 0;
Node<T> *p = head;
while (p){
++n;
p = p->next;
}
return n;
}
void clear(){
Node<T> *p = head;
while(p){
Node<T>* q = p-> next;
delete[] p;
p = q;
}
head = tail = nullptr;
}
~List<T>(){
clear();
}
};
template<typename T>
List<T>::List(std::initializer_list<T> list)
{
for (T const& elem : list)
push_back(elem);
}
主:
int main()
{
List<String> v1 = {"a", "b", "c"}; //segfault occurs on second pass of initialization loop
return 0;
}
感谢任何帮助!
答案 0 :(得分:2)
节点(我知道这并没有实现&#39;三巨头&#39;,我宁愿将这个课程保持在最低限度):
您应该注意,复制/移动构造函数和赋值运算符仍然以compiler generated default versions提供。
为了避免在您不想实施big three (or five)的情况下,您需要明确地delete
:
class String{
public:
int len;
char *str;
String()
:len(0), str(nullptr){}
String(char const* S)
:len(strlen(S)), str(new char[len +1]){
assert(S != 0);
strcpy(str, S);
}
// Add these:
String(const String&) = delete;
String(String&&) = delete;
String& operator=(const String&) = delete;
String& operator=(String&&) = delete;
~String(){
delete[]str;
}
};