在哪里删除使用链接列表实现的堆栈中的node->日期

时间:2013-06-27 21:55:55

标签: c++ data-structures stack

当我实现保存节点的堆栈的pop()和析构函数时,我应该在删除节点本身之前删除node->数据,还是应该删除节点并让创建node->数据的调用者删除node->数据?如果让调用者这样做,调用者何时以及如何删除数据?它应该以这种方式调用:{data = stack.top();删除数据; stack.pop();}?

我还没有看到任何删除node->数据的代码,无论是pop()的实现还是调用函数。这就是为什么我感到困惑。

这里我复制了我使用链接列表实现的堆栈。请查看pop()和~stack()的注释以解决我的问题。谢谢你的帮助。

typedef struct Node_t{
    struct Node_t* next;
    void* data;
}Node; 

class stack {
public: 
    stack(): _head(null), _size(0){}
    ~stack();
    void push(void* data);
    void pop();
    void* top();
    bool empty();
    stack(const stack& original);
    stack& operator=(const stack& original);    
private:
    Node* _head;    
    int _size;  
};
stack::~stack{
 Node* next = null;
 while(_head){
      next = _head->next;
      //should delete _head->_data???
      delete _head;                     
      _head = next;
 }
 _size = 0;
}
void stack::push(void* data){
    Node* elem = new Node;
    elem->data = data; 
    elem->next = _head;
   _head = elem;
    _size++;
}    

void stack::pop(){
Node* next = NULL;
if (_head) {
   next = _head->next;
   //should delete _head->_data???
   delete _head;
   _head = next;        
   _size--;
}
}    

void* stack::top() const{
if (_head) {
   return _head->_data;
}        
}

bool stack::empty(){
   if(_size>0) return false;
   else return true;
}

2 个答案:

答案 0 :(得分:2)

您的数据是指向其他地方的指针。这里的策略是:在堆栈外部创建数据对象,并将数据指针推入堆栈。因此,通过对称性,删除数据的控制也应该存在于堆栈的外面。如果您不需要,则需要明确删除它。例如:

stack s;
char mydata[] = {'a','b','c'};
s.push((void*)mydata);
//do things
s.pop();
delete [] mydata;

如果你真的想控制堆栈中的数据(通过它可能不是一个好主意,假设你的数据可能在其他地方使用),那么也存在问题。因为数据类型无效*您可能无法“安全地”删除它。请参阅此主题Is it safe to delete a void pointer?

答案 1 :(得分:1)

这个答案有几个部分:

  1. 对于实际编程,没有理由建立自己的数据结构,而标准库已经提供了这些数据结构。

  2. 如果你必须建立自己的数据结构作为学习练习,原则上你可以拥有你想要的任何分配和删除语义。

  3. 但是,如果你必须构建自己的堆栈,我强烈建议遵循与标准库stack相同的语义,它使用复制和引用语义来避免显式分配和删除用户代码。

  4. 遵循标准库语义可提高一致性,减少理解界面时的认知负担,并大大降低内存泄漏的可能性。