为什么我的代码没有设置变量?

时间:2014-01-26 07:19:12

标签: c++ g++

队列的目的是存储指向T类型的对象的指针。当我遍历各种数据结构时,队列用于在队列中推送和弹出对象。

除了以下行之外,队列工作正常:

out = t->payload;

(从底部四行)

out永远不会改变t->payload中的值。在调试器中查看它,我可以看到t->payload设置正确,但out未分配t->payload中的值。有人能告诉我发生了什么吗?

template<typename T>
class Queue
{
private:
    struct node
    {
        T           *payload;
        struct node *next;
    };
    node *head;
    node *tail;
public:
    Queue()
    {
            head = new node;
        tail = new node;
        head->next = tail;
        tail->next = tail;
    }
        ...
    void push(T *payload)
    {
        node *newNode;
                node *temp;
        newNode = new node;
        temp = head->next;
        head->next = newNode;
        newNode->next = temp;
        newNode->payload = payload;
    }
    bool pop(T *out)
    {
        node *t;
        node *x;
        t = head;
        x = head;
        if(t == tail)
        {
            return false;  //already empty
        }
        while(t->next != tail)
        {
            x = t;
            t = t->next;
        }
        x->next = tail;
        out = t->payload;
        delete t;
        return true;
    }
}

5 个答案:

答案 0 :(得分:1)

bool pop(T *out)
T *payload;
out = t->payload;  

您正在将T *复制到T *,但目标是一个函数参数,它总是“在”中。使用函数结果,或T ** out或T *&amp;进行。

答案 1 :(得分:1)

严格来说,我无法重现您的错误:out被设置为函数中t->payload ... 的值。

bool pop(T *out)
{
  ...
  out = t->payload;
  ...
}

按值传入指针out。该函数修改指针out,它是一个局部变量,它在调用函数时指向的东西,而不是可能作为调用代码中的变量存在的指针。

答案 2 :(得分:0)

  

out = t->payload;

这是您的问题的根源。您正在切断传递给函数的参数之间的链接。您的参数out是指针。如果你想使用这个范例(注意:不是最好的主意),你永远不应该改变out。您应该改为通过

更改out的内容
*out = *(t->payload);

以上有两个关键问题。如果outt->payload是空指针,则会出现这种情况。您可以通过传递引用而不是指针来修复前一个问题。如果您这样做,那么您应该使用out = *(t->payload)。这不能解决空载荷的问题。您可以通过确保在添加节点时有效负载始终为非null来解决此问题。

然而,问题仍然存在。例如,如果删除该有效负载指针,使取消引用无效,该怎么办?使用指针总是有点问题。

答案 3 :(得分:0)

请注意,如果容器不强制客户端上的指针类型,则容器会更好。下面给出的非常简单的示例避免了签名中的明确星号(*)。因此,对于用户是否信任具有普通类型或指针类型的守护者是开放的。无论哪种方式,数据都可以简单地复制到“keep”实例变量中。如果她决定使用指针,那很好,但分配和释放动态内存的责任在于她。

template<typename T>
class Keeper {
public:
  Keeper() : keeping(false){}
  virtual ~Keeper(){}
  void push( T & payload ){
    if( keeping ) throw "I'm busy";
    keeping = true;
    keep = payload;
  }
  bool pop( T & payload ){
    if( ! keeping ) return false;
    keeping = false;
    payload = keep;
    return true;
  }
private:
  bool keeping;
  T keep;
};

答案 4 :(得分:-1)

尝试在创建新对象时添加一些括号。

像这样:

head = new node();
tail = new node();
...

有关其重要性的进一步说明,请参阅以下链接:

Do the parentheses after the type name make a difference with new?

Not using parentheses in constructor call with new (c++)

编辑:在代码中添加了一些打印语句。这个问题似乎有两个方面。

  1. 在push中,而不是将newNode-&gt; payload设置为payload,尝试将其设置为new int(* payload)。这样就会复制价值。
  2. 在弹出结束时,您将out的地址设置为t-&gt; payload,但是t之后被删除,因此out指向什么都没有。而是如上所述复制值。
  3. 如果你纠正这两件事,它似乎有效!

    编辑2:将其作为参考实施

    bool pop(T &out)
    {
        node *t;
        node *x;
        t = head;
        x = head;
        if(t == tail)
        {
            return false;  //already empty
        }
        while(t->next != tail)
        {   
            x = t;
            t = t->next;
        }
        x->next = tail;
        out = *(t->payload);
        delete t;
        return true;
    }