C++访问违规?

发布于 2024-12-07 03:30:04 字数 634 浏览 2 评论 0原文

当我在 Linux 中编码时,如果相同的代码工作得很好,为什么我会在此处读取位置 0xC0000005 时出现访问冲突?

if(nodo->izq!=NULL) //nodo is a class or struct and "sig" is a pointer of the same kind
    VaciarAux(nodo->izq);

有什么方法可以在没有未处理异常的情况下完成此操作吗? 断言能解决问题吗?

这是函数

void Arbol<T>::VaciarAux(Nodo<T> * &nodo)
{
    if(nodo->izq!=NULL)
        VaciarAux(nodo->izq);
    if(nodo->der!=NULL)
        VaciarAux(nodo->der);
    if(nodo->izq == NULL && nodo->der ==NULL)
    {
        actual = nodo;
        nodo=NULL;
        delete actual;
        contador--;
    }

Why am I getting an access violation reading location 0xC0000005 here if the same code works like a charm when I coding in linux?

if(nodo->izq!=NULL) //nodo is a class or struct and "sig" is a pointer of the same kind
    VaciarAux(nodo->izq);

Is there any way of getting this done without that unhandled exception?
assert will do the trick?

here is the function

void Arbol<T>::VaciarAux(Nodo<T> * &nodo)
{
    if(nodo->izq!=NULL)
        VaciarAux(nodo->izq);
    if(nodo->der!=NULL)
        VaciarAux(nodo->der);
    if(nodo->izq == NULL && nodo->der ==NULL)
    {
        actual = nodo;
        nodo=NULL;
        delete actual;
        contador--;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷乱花海 2024-12-14 03:30:04

很可能是因为 nodo 本身是一个无效的指针。 -> 取消引用会导致问题。

您需要检查可能影响该值的因素(缓冲区溢出导致损坏,由于某种原因设置为 NULL)。

请注意:

if (nodo->izq != NULL)

检查nodo变量是否为NULL,而是检查nodo指向的izq成员to 为 NULL。

如果你只是想在 nodo 本身为 NULL 的情况下什么都不做,你可以在开头加上:

if (nodo == NULL) return;

但我仍然认为你最好追溯到问题的根源,而不是仅仅修复一种症状。


我认为问题在于你处理树的方式。你正在有效地做:

def delTree (node):
    if node.left != NULL:
        delTree (node.left)
    if node.right != NULL:
        delTree (node.right)
    if node.left == NULL and node.right == NULL:
        delete node and whatever else you have to do

主要问题是 delTree (node.left) 意味着你会得到你所看到的确切问题,如果树是空的,因为你第一次尝试所做的就是取消引用 NULL 根节点。

更常见的方法是首先无条件地重复子节点(使用 NULL 保护器),然后处理节点本身,如下所示:

def delTree (node):
    if node == NULL:
        return
    delTree (node.left)
    delTree (node.right)
    delete node and whatever else you have to do

这将正确处理空树,并且仍然正确删除父节点之前的所有子节点。而且它看起来更优雅,这也是首先使用递归的原因之一:-)

我将把它作为练习,让读者将其转回 C++。

Most likely because nodo itself is an invalid pointer. The -> dereferencing would then cause a problem.

You need to check the things that could possibly affect that value (buffer overflows causing corruption, having set to NULL for some reason).

Note that:

if (nodo->izq != NULL)

does not check if the nodo variable is NULL but rather if the izq member of what nodo points to is NULL.

If you simply want to do nothing if nodo itself is NULL, you could put at the start:

if (nodo == NULL) return;

but I still think you'd be much better off tracking back to the source of the problem rather than just fixing one symptom.


I think the problem is with the way you are processing the tree. You are effectively doing:

def delTree (node):
    if node.left != NULL:
        delTree (node.left)
    if node.right != NULL:
        delTree (node.right)
    if node.left == NULL and node.right == NULL:
        delete node and whatever else you have to do

The main problem with that is that delTree (node.left) means that you'll get the exact problem you're seeing if the tree is empty since the first thing you try to do is dereference the NULL root node.

The more usual approach is to first recur the children unconditionally (with a NULL protector) then process the node itself, something like:

def delTree (node):
    if node == NULL:
        return
    delTree (node.left)
    delTree (node.right)
    delete node and whatever else you have to do

This will correctly handle an empty tree and still correctly delete all children before the parent. And it just looks more elegant, which is one of the reasons to use recursion in the first place :-)

I'll leave it as an exercise for the reader to turn that back into C++.

土豪 2024-12-14 03:30:04

正如帕克斯所说,这可能是一个糟糕的指针。在 Linux 中,可能没有像在其他地方运行代码时那样严格的虚拟内存规则(也取决于编译器)。因此,在 Linux 情况下,它可能会起作用,但实际上可能会做一些您意想不到的事情。

As pax says it's probably a bad pointer. In Linux there may not be strict virtual memory rules as when running the code somewhere else (also depends on the compiler). So in the Linux case it might be working but it might actually be doing something you don't expect.

酷炫老祖宗 2024-12-14 03:30:04

您可能想了解一下如何创建 Nodo 类型(即查看其默认构造函数……它应该有一个,因为它是一个包含指针的类/结构)。例如,如果您没有初始化 Nodo 类型的成员,以便在创建 Nodo 对象时两个指针成员最初为 NULL ,那么它们可能具有任何不确定的值,从而导致对 Arbol::VaciarAux 内部的 NULL 值的测试将失败。例如,一个新的 Nodo 最终会得到初始化为某个随机值的指针,但是 Nodo 的指针成员中包含的那些随机内存值不是可访问的有效位置。记忆。然后,当您测试指针是否为 NULL 时,测试结果为 false,并且您尝试在下一次递归调用 Arbol::VaciarAux 时取消引用它们,导致访问冲突。

You may want to look into how you are creating a Nodo type (i.e., look at its default constructor ... it should have one since it's a class/struct that contains pointers). For instance, if you are not initializing the members of a Nodo type so that the two pointer members are initially NULL whenever a Nodo object is created, then they could have any indeterminant value such that the tests for NULL values inside of Arbol<T>::VaciarAux will fail. For instance, a new Nodo would end up with pointers initialized to some random value, but those random memory values contained in the pointer-members of Nodo are not valid locations accessible in memory. Then when you test whether the pointers are NULL, the test comes out false, and you attempt to dereference them in the next recursive call to Arbol<T>::VaciarAux, causing an access violation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文