【发布时间】:2017-01-22 03:24:12
【问题描述】:
您好,我正在编写自己的列表类,实际上它的工作方式类似于 std::vector 类。问题是当我使用new 为下一个列表分配内存时,
它工作正常。但是当我尝试为目标(数据)分配内存时,它会在程序到达 push_back() 范围的末尾时被回收
我不明白为什么这两个不会以同样的方式发生,我怎样才能将分配的内存用于我的数据而不会被破坏?
代码在这里
#include <iostream>
#include <cstdlib>
using namespace std;
struct pos{
int x;
int y;
pos()
{
x = y = 0;
}
pos(int x, int y)
{
this->x = x;
this->y = y;
}
pos& operator=(pos rhs)
{
x = rhs.x;
y = rhs.y;
return *this;
}
bool operator==(const pos& rhs)
{
if(x == rhs.x && y == rhs.y)
return true;
else
return false;
}
~pos()
{
cout << "x =" << x << ", y =" << y << "got distorted!" << endl;
}
};
class list {
private:
pos *target;
list* next;
int index;
public :
list();
list(pos target);
void push_back (int first , int second);
void push_back (const pos target);
pos pop_back();
pos* search(int first , int second);
pos* search(pos target);
int erase(int index);
pos get(int index);
void change(const pos target,int index);
void change(int first,int second,int index);
~list();
};
void print(list lst);
// function declarations
list::~list()
{
cout << "list is destroyed!" << endl;
if(target != NULL)
delete target;
if(next != NULL)
delete next;
}
list::list()
{
target = NULL;
next = NULL;
index = 0;
}
list::list(pos target)
{
this->target = new pos(target);
index = 0;
next = NULL;
}
void list::push_back(const pos target)
{
cout << "push_back() begin" << endl;
list* it = this;
while(it->next != NULL)
{
it = it->next;
}
if(it->target == NULL)
{
it->target = new pos(target);
}
else
{
it->next = new list;
it->next->index = it->index+1;
//option one
it->next->target = new pos(target);
//option two
it->next->target = (pos*)malloc(sizeof(pos));
(*it->next->target) = target;
//it->next->next is already NULL
}
cout << "push_back() end" << endl;
}
void list::push_back(int first , int second)
{
push_back(pos(first,second));
}
pos list::pop_back()
{
print(*this);
list* it = this;
cout << "address of x is" << this << endl;
cout << "this->target is" << this->target << endl;
cout << (*target).x << endl;
if(it->target == NULL)
return *(new pos); // an error is occurred there is not any data to return! must find another solution maybe throw an exception
if(it->next == NULL)
{
pos return_data = *(it->target);
delete it->target;
it->target = NULL;
return return_data;
}
while(it->next->next != NULL)
{
cout << "it->target is" << it->target << endl;
it = it->next;
}
pos return_data = *(it->next->target);
delete it->next;
it->next = NULL;
return return_data;
}
pos* list::search(pos target)
{
list* it = this;
do
{
if(target == *(it->target))
return it->target;
if(it->next != NULL)
it = it->next;
else
return NULL;
}while(1);
}
pos* list::search(int first , int second){
return search(pos(first,second));
}
int list::erase(int index){
if(index < 0)
return 0;
list *it = this , *it_next = this->next;
if(index == 0)
{
if(it->next == NULL)
{
delete it->target;
return 1;
}
while(it_next->next != NULL)
{
it->target = it_next->target;
it = it_next;
it_next = it_next->next;
}//needs to be completed
}
do
{
if(it_next->index == index)
{
it->next = it_next->next;
delete it_next;
return 1;
}
if(it_next->next != NULL)
{
it = it_next;
it_next = it_next->next;
}
else
return 0;
}while(1);
return 1;
}
pos list::get(int index)
{
if(index < 0)
return *(new pos);//error
list* it = this;
do
{
if(it->index == index)
{
return *(it->target);
}
if(it->next != NULL)
it = it->next;
else
return *(new pos);//error , index is bigger than [list size] - 1
}while(1);
}
void list::change(const pos target,int index)
{
if(index < 0)
return ;//error
list* it = this;
do
{
if(it->index == index)
{
*(it->target) = target;
}
if(it->next != NULL)
it = it->next;
else
return;//error , index is bigger than [list size] - 1
}while(1);
}
void list::change(const int first,const int second,int index)
{
change(pos(first,second),index);
}
void print(list lst)
{
int idx = 0;
while(!(lst.get(idx)==pos(0,0)))
{
cout << "index " << idx << " : x = " << lst.get(idx).x << ", y = " << lst.get(idx).y << endl;
idx++;
}
}
int main(int argc, char const *argv[])
{
list x;
cout << "address of x is" << &x << endl;
x.push_back(1,1);
x.push_back(2,2);
x.push_back(3,3);
x.push_back(4,4);
x.push_back(5,5);
print(x);
cout << "--------------------------" << endl;
x.pop_back();
print(x);
cout << "--------------------------" << endl;
cout << x.get(2).x << endl;
x.erase(2);
print(x);
cout << "--------------------------" << endl;
return 0;
}
换句话说,为什么 it->next->target 和/或 it->target 在 push_back 返回时被销毁?
【问题讨论】:
-
附带说明,两者
new和malloc为数据分配内存。你需要改写你的问题。如果可能,请发布MCVE。 -
您的代码不符合Rule of Three。示例:查看
print如何通过值获取list,这意味着传递参数使用默认的成员复制复制ctor,这意味着您现在有两个list对象,其成员指向same 动态内容。当print存在时,复制的参数被销毁,帽子数据的原始合法所有者回到main(),并带有一堆悬空指针。 -
那么我应该怎么做才能保证原始列表的安全呢?
标签: c++ pointers memory-management