C++访问违规?
当我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
很可能是因为
nodo
本身是一个无效的指针。->
取消引用会导致问题。您需要检查可能影响该值的因素(缓冲区溢出导致损坏,由于某种原因设置为 NULL)。
请注意:
不检查
nodo
变量是否为NULL,而是检查nodo
指向的izq
成员to 为 NULL。如果你只是想在
nodo
本身为 NULL 的情况下什么都不做,你可以在开头加上:但我仍然认为你最好追溯到问题的根源,而不是仅仅修复一种症状。
我认为问题在于你处理树的方式。你正在有效地做:
主要问题是
delTree (node.left)
意味着你会得到你所看到的确切问题,如果树是空的,因为你第一次尝试所做的就是取消引用 NULL 根节点。更常见的方法是首先无条件地重复子节点(使用 NULL 保护器),然后处理节点本身,如下所示:
这将正确处理空树,并且仍然正确删除父节点之前的所有子节点。而且它看起来更优雅,这也是首先使用递归的原因之一:-)
我将把它作为练习,让读者将其转回 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:
does not check if the
nodo
variable is NULL but rather if theizq
member of whatnodo
points to is NULL.If you simply want to do nothing if
nodo
itself is NULL, you could put at the start: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:
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:
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++.
正如帕克斯所说,这可能是一个糟糕的指针。在 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.
您可能想了解一下如何创建
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 aNodo
type so that the two pointer members are initiallyNULL
whenever aNodo
object is created, then they could have any indeterminant value such that the tests forNULL
values inside ofArbol<T>::VaciarAux
will fail. For instance, a newNodo
would end up with pointers initialized to some random value, but those random memory values contained in the pointer-members ofNodo
are not valid locations accessible in memory. Then when you test whether the pointers areNULL
, the test comes out false, and you attempt to dereference them in the next recursive call toArbol<T>::VaciarAux
, causing an access violation.