【问题标题】:In C++, how to I stop my pointers from being 'overridden' when a function is called again?在 C++ 中,当再次调用函数时,如何阻止我的指针被“覆盖”?
【发布时间】:2010-10-06 13:44:00
【问题描述】:

全部!我不知道“覆盖”是否是正确的词。在我的 编程类,我要创建一个循环列表,这样每个节点 node 包含一个指向下一个节点和最后一个节点的指针 指向第一个节点。此外,还有一个尾节点指向 添加的最后一个节点(在添加任何节点之前为 null)。

我无法填充我的列表(称为响铃),因为每次我调用 Ring::Insert(const int& d) 函数,插入单个节点,它 到达“RingNode newNode(d);”行,新的 RingNode 对象 覆盖我上次创建的上一个 RingNode 对象 称为 Ring::Insert(const int& d) 函数。很明显,我不想 这是因为它弄乱了我的清单。每次我如何做到这一点 函数创建一个全新的 RingNode 对象,它不会干扰 以前的 RingNode 对象?

我的头文件中的源代码,以防万一:

class RingNode {
public:
    RingNode(const int& i=0 ): data(i), next(NULL){}
private:
    int data;  /* ID of player */
    RingNode* next;
friend class Ring;

这是有问题的功能

RingNode* Ring::Insert(const int& d){
    RingNode newNode(d); //This line overwrites previous RingNode objects
    RingNode* refNode = &newNode; //Probably bad form, but that's not my main concern right now
    if (tail==null){
            tail = refNode;
            newNode.next = refNode;
            return refNode;
    }
    newNode.next = (*GetTail()).next;
    (*GetTail()).next = refNode;
    tail = refNode;
    return refNode;
}

因此,例如,如果我在我的 main 中执行以下 sn-p...

Ring theRing;
theRing.Insert(5);
theRing.Insert(2);
theRing.Insert(7);

如果我调试我的项目,我可以看到 theRing 只包含一个 RingNode, 首先是 5 RingNode,然后是 2 RingNode 覆盖它,然后是 7 RingNode 会覆盖它。感谢您的阅读并再次感谢您的 回复!

编辑:我替换了

RingNode newNode(d); 
RingNode* refNode = &newNode;

RingNode *newNode = new RingNode(d);

调整了其余的代码,它工作正常。非常感谢你们的帮助,伙计们!非常有用,最重要的是我现在明白了为什么它搞砸了。

【问题讨论】:

  • 请务必接受您的问题的答案。

标签: c++ pointers function


【解决方案1】:

您每次都在堆栈上重复使用相同的局部变量。

RingNode newNode(d); //This line overwrites previous RingNode objects

是一个局部变量 - 它存在于堆栈中。所以它只在你的插入方法的生命周期内有效。但是,由于您在同一调用函数中连续多次调用 insert,因此您的不同“newNode”最终会在堆栈上的同一位置结束。

你可能想做的是

RingNode *refNode = new RingNode(d);

这将在堆上动态分配您的 RingNode。

但是,现在您必须担心在 Ring 被销毁时使用 delete 来清理所有节点。

【讨论】:

  • 实际上,我有点怀疑这就是他想要的:他可能想要某种智能指针来避免处理手动内存管理的麻烦。
  • @Matthieu M:一般我会同意你的观点,但在这种情况下,这是一个编程课的作业。通常在这些课程中,重点是教他们正确处理原始指针。然后,一旦他们知道原始指针有多糟糕,他们就可以在实际任务中使用智能指针。
  • 智能指针有其用途,但在这种情况下,当指针使用(显然)完全封装在外部 Ring 类中时,智能指针可能只是不必要的开销。
  • 确实,这是一个教科书示例,说明智能指针可能是一个 bad 选项。智能指针对于很难测试资源是否被正确释放的大型程序很有用;对于小型、封装良好、易于测试的类,它们充其量会导致效率低下,而在最坏的情况下会导致错误。
【解决方案2】:
环节点新节点(d); RingNode* refNode = &newNode;

替换为:

RingNode* refNode = new RingNode(d);

顺便说一句,替换

RingNode(const int& i=0 )

与:

环节点(int i=0)

对于像整数这样的小类型,不需要使用引用。

【讨论】:

    【解决方案3】:

    您需要创建超出函数范围的对象...因此您需要使用new 运算符。

    RingNode* Ring::Insert(const int& d){
        RingNode* refNode = new RingNode(d); // this line creates a ring node not bound to the scope of the function.
        if (tail==null){
                tail = refNode;
                newNode.next = refNode;
                return refNode;
        }
        newNode.next = (*GetTail()).next;
        (*GetTail()).next = refNode;
        tail = refNode;
        return refNode;
    }
    

    【讨论】:

      【解决方案4】:

      您不能像这样添加分配为“自动”变量的对象,即在堆栈上。你需要做RingNode *newNode = new RingNode(d); 并添加它。

      【讨论】:

        猜你喜欢
        • 2022-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-27
        • 1970-01-01
        • 1970-01-01
        • 2013-01-16
        • 1970-01-01
        相关资源
        最近更新 更多