智能指针存在问题。我创建了一个简单的类“Container”,它复制了一个双链表。我在smartp中使用了引用计数,一切正常,但是使用简单的main.cpp文件测试我遇到了问题。最后一个尾部地址是错误的,它在简单的pop_front之后发生了变化。
另一个问题是“删除pv”,如果我从评论标签中删除它会导致分段错误。谁能帮我?感谢
这是头文件:
#ifndef CONTAINER_H
#define CONTAINER_H
#include<ostream>
using namespace std;
template<class K>
class container {
friend class iteratore;
private:
class nodo;
class smartp {
public:
nodo* ptr;
smartp(nodo*);
smartp(const smartp&);
~smartp();
smartp& operator=(const smartp&);
nodo& operator*() const;
nodo* operator->() const;
bool operator==(const smartp&) const;
bool operator!=(const smartp&) const;
};
class nodo {
public:
K info;
smartp prev;
smartp next;
int refer;
nodo();
nodo(const K&, const smartp&, const smartp&);
};
smartp head;
smartp tail;
public:
container();
// ~container();
class iteratore {
friend class container<K>;
private:
smartp punt;
iteratore(smartp n): punt(n) {}
public:
iteratore(): punt(0) {}
bool operator==(iteratore) const;
bool operator!=(iteratore) const;
iteratore& operator++();
iteratore operator++(int);
iteratore& operator--();
iteratore operator--(int);
K& operator*() const;
K* operator->() const;
};
iteratore begin() const;
iteratore end() const;
K& operator[](iteratore) const;
void push_back(const K&);
void push_front(const K&);
void insert(const iteratore&, const K&);
void printDB();
void pop_back();
void pop_front();
bool isEmpty() const;
iteratore erase(iteratore);
};
// INIZIO SMARTP
template<class K>
container<K>::smartp::smartp(nodo* p = 0): ptr(p) {
if(ptr) ptr->refer++;
}
template<class K>
container<K>::smartp::smartp(const smartp& s): ptr(s.ptr) {
if(ptr) ptr->refer++;
}
template<class K>
container<K>::smartp::~smartp() {
if(ptr != 0) {
ptr->refer--;
if(ptr->refer == 0) {
cout << " ~smartp ";
delete ptr;
}
}
}
template<class K>
typename container<K>::smartp& container<K>::smartp::operator=(const smartp& s) {
if(this != &s) {
nodo* t = ptr;
ptr = s.ptr;
if(ptr) ptr->refer++;
if(t) {
t->refer--;
if(t->refer == 0) delete t;
}
}
return *this;
}
template<class K>
typename container<K>::nodo& container<K>::smartp::operator*() const {
return *ptr;
}
template<class K>
typename container<K>::nodo* container<K>::smartp::operator->() const {
return ptr;
}
template<class K>
bool container<K>::smartp::operator==(const smartp& p) const {
return ptr == p.ptr;
}
template<class K>
bool container<K>::smartp::operator!=(const smartp& p) const {
return ptr != p.ptr;
}
// FINE SMARTP
template<class K>
container<K>::nodo::nodo(const K& i, const smartp& p, const smartp& n): info(i), prev(p), next(n), refer(0) {}
template<class K>
container<K>::nodo::nodo(): refer(0) {}
template<class K>
container<K>::container(): head(0), tail(0) {}
/*
template<class K>
container<K>::~container() {
int i = 0;
while(!isEmpty()) {
cout << " " << i;
pop_front();
cout << " " << i++;
}
}
*/
template<class K>
void container<K>::push_back(const K& k) {
nodo* aux = new nodo(k, tail, 0);
if(isEmpty()) { // lista vuota
head = tail = aux;
} else {
tail->next = aux;
tail = aux;
}
tail->refer--;
}
template<class K>
void container<K>::push_front(const K& k) {
nodo* aux = new nodo(k, 0, head);
if(isEmpty()) { // lista vuota
head = tail = aux;
} else {
head->prev = aux;
head = aux;
}
head->refer--;
}
template<class K>
void container<K>::insert(const iteratore& it, const K& k) { // inserisce k prima dell'elemento puntato da it
nodo* aux = new nodo(k, it.punt->prev, it.punt);
if(it.punt->prev != 0) { // se it ha un nodo precedente (cioè se it non è la testa)
it.punt->prev->next = aux;
} else {
head = aux;
}
it.punt->prev = aux;
}
template<class K>
void container<K>::printDB() {
cout << "/**/IND-H: " << &head.ptr->info << endl;
smartp aux = head;
while(aux.ptr != 0) {
cout << aux.ptr->info;
cout << " *IND:" << aux.ptr << "* "<<endl;
aux = aux.ptr->next;
}
cout << "/**/IND-T: " << &tail.ptr->info;
cout << endl << endl;
}
template<class K>
void container<K>::pop_back() {
if(!isEmpty()) {
smartp aux = tail->prev;
delete &tail;
tail = aux;
if(aux!=0) tail->next = 0;
else head = aux;
}
}
template<class K>
void container<K>::pop_front() {
if(!isEmpty()) {
smartp aux = head->next;
delete &head;
head = aux;
if(aux!=0) head->prev = 0;
else tail = aux;
}
}
template<class K>
bool container<K>::isEmpty() const {
return head == 0;
}
template<class K>
typename container<K>::iteratore container<K>::erase(iteratore it) {
iteratore aux = it.punt->next;
if(it.punt->prev == 0) pop_front(); // it = head
else if(it.punt->next == 0) pop_back(); // it = tail
else {
it.punt->next->prev = it.punt->prev;
it.punt->prev->next = it.punt->next;
delete &(it.punt);
}
return aux;
}
template<class K>
bool container<K>::iteratore::operator==(iteratore i) const {
return punt == i.punt;
}
template<class K>
bool container<K>::iteratore::operator!=(iteratore i) const {
return punt != i.punt;
}
template<class K>
typename container<K>::iteratore& container<K>::iteratore::operator++() {
if(punt != 0) punt = punt->next;
return *this;
}
template<class K>
typename container<K>::iteratore container<K>::iteratore::operator++(int) {
iteratore aux = *this;
if(punt != 0) punt = punt->next;
return aux;
}
template<class K>
typename container<K>::iteratore& container<K>::iteratore::operator--() {
if(punt != 0) punt = punt->prev;
return *this;
}
template<class K>
typename container<K>::iteratore container<K>::iteratore::operator--(int) {
iteratore aux = *this;
if(punt != 0) punt = punt->prev;
return aux;
}
template<class K>
K& container<K>::iteratore::operator*() const {
return punt->info;
}
template<class K>
K* container<K>::iteratore::operator->() const {
return &(punt)->info;
}
template<class K>
typename container<K>::iteratore container<K>::begin() const {
iteratore aux;
aux.punt = head; // per amicizia
return aux;
}
template<class K>
typename container<K>::iteratore container<K>::end() const {
iteratore aux;
aux.punt = 0; // per amicizia
return aux;
}
template<class K>
K& container<K>::operator[](typename container<K>::iteratore it) const {
return (it.punt)->info; // per amicizia
}
#endif // CONTAINER_H
这是测试主文件:
#include <iostream>
#include"container.h"
using namespace std;
int main()
{
container<int>* pv = new container<int>;
cout << "Inserisco in coda: 9" << endl;
pv->push_back(9);
pv->printDB();
cout << "Inserisco in coda: 5, 2" << endl;
pv->push_back(5);
pv->push_back(2);
pv->printDB();
cout << "Inserisco in testa: 1, 7" << endl;
pv->push_front(1);
pv->push_front(7);
pv->printDB();
cout << "Faccio pop_back()" << endl;
pv->pop_back();
pv->printDB();
cout << "Faccio pop_front()" << endl;
pv->pop_front();
pv->printDB();
// delete pv;
cout <<"FINE"<< endl;
}
答案 0 :(得分:0)
此构造不正确且具有未定义的行为:
delete &tail;
// ...
delete &head;
因为&tail
和&head
未使用new
动态分配。
由于你有智能指针,所以你不应该在智能指针的析构函数之外使用delete
。