如何在不导致分段错误的情况下删除堆上的对象

How to delete object on heap without causing segmentation fault

嗨(我是一名正在努力学习的 C++ 学生,请不要在高级阶段烤我),

我在堆上的对象上创建了 temArr。当我 运行 它没有删除堆上的 temArr 时,我的程序编译没有问题,但是当我 运行 它通过 valgrind 时,temArr 上存在内存泄漏。但是当我运行它与delete temArr; temArr = nullptr;。我遇到分段错误。

我试图在堆栈上做到这一点: NodeList* n1(0); n1 = temArr; return n1->getNode(Index); < 这行得通,但是 delete temArr; temArr = nullptr; 它 return 的随机变量是不正确的。

有没有办法可以将堆上的值放入堆栈中删除堆,然后 return 堆栈上的对象?或者我是否错误地删除了我的堆,从而导致分段错误?

代码:

Node *PathSolver::findShortDis(NodeList *openList, Node *nodeG, NodeList *closeList) {

    int Index =0;
    
    NodeList* temArr = new NodeList();
    
    for (int x = 0; x < openList->getLength(); x++) {
        if (closeListCheck(openList->getNode(x), closeList)) {
            temArr->addElement(openList->getNode(x));
        }
    }
    //assign tem to the very first node of temA
    int tem = temArr->getNode(0)->getEstimatedDist2Goal(nodeG);

    //compare
    for (int x = 0; x < temArr->getLength(); x++) {
        if (temArr->getNode(x)->getEstimatedDist2Goal(nodeG) <= tem) {
            tem = temArr->getNode(x)->getEstimatedDist2Goal(nodeG);
            Index = x;
        }
    }

    for(int x = 0; x <  temArr->getLength(); x++) {
        if (openList->getNode(x)->getCol() == temArr->getNode(Index)->getCol()
        && openList->getNode(x)->getRow() == temArr->getNode(Index)->getRow()){
            Index = x;
        }
    }

    // NodeList* n1(0);
    // n1 = temArr;
    // return n1->getNode(Index);

    // delete temArr;
    // temArr = nullptr;

    return temArr->getNode(Index);

}

先谢谢你。

如果您取消注释您的 delete temArr 行,您的 return 语句将在删除后尝试访问 temArr 变量。这是未定义的行为,任何事情都可能发生,从获取随机值到段错误。

您的 temArr 不需要动态分配,只需在堆栈上创建它即可,问题是您正在 returning 的 Node* 指针发生了什么在你的 NodeList 被删除之后,但我们不能在没有看到其余代码的情况下说出来。

调用成员函数时,您必须将所有 -> 运算符更改为 .

NodeList temArr{}; // Create NodeList on the stack
.
.
.
return temArr.getNode(index);

你也可以在旁边存储你想要的值return,删除对象然后return。

Node* returnValue = temArr->getNode(Index);
delete temArr;
return returnValue;

或者使用智能指针,它会动态分配对象,但当它离开作用域时将其删除。

std::unique_ptr<NodeList> temArr = std::make_unique<NodeList>();
.
.
.
return temArr->getNode(index);

在堆栈上创建 temArr(第一个代码)是 easiest/best 解决方案,但是 确保 值 returned在所有 3 种情况下,getNode 方法有效 之后 NodeList 已被删除。

段错误的原因是您正在尝试访问已删除的内存,换句话说,在行中:return temArr->getNode(Index)您正在从悬空指针读取。 有几种方法可以解决这个问题,我会建议你最简单的。

你可以直接在栈上分配temArr(这是最简单的方法,但如果NodeList太大也不好)。 使用此方法,将在函数结束时调用 NodeList 对象的析构函数,并正确释放资源。