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



嗨(我是一名C++学生,正在努力学习plz,不要在高级阶段吐槽我(,

我在堆上创建了temArr作为on对象。当我在不删除堆上的temArr的情况下运行程序时,我的程序编译没有问题,但当我通过valgrind运行它时,temArr上存在内存泄漏。但当我用delete temArr;temArr = nullptr;运行它时。我有一个分割错误。

我试着在堆栈上做这个:NodeList* n1(0); n1 = temArr; return n1->getNode(Index);<这是有效的,但当执行delete temArr;temArr = nullptr;时,它返回不正确的随机变量。

有没有一种方法可以让堆上的值放入堆栈中,删除堆,然后返回堆栈上的对象?或者我删除我的堆是错误的,所以它给出了分段错误?

代码:

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变量。这是未定义的行为,任何事情都可能发生,从获取随机值到segfault。

您的temArr不需要动态分配,只需在堆栈上创建它,在NodeList被删除后,您返回的Node*指针会发生什么问题,但我们不能不看到代码的其余部分。

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

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

您还可以将要返回的值存储在侧面,删除对象,然后返回。

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

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

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

在堆栈上创建temArr(第一个代码(是最简单/最好的解决方案,但在所有三种情况下,请确保删除NodeListgetNode方法返回的值有效。

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

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

相关内容

最新更新