C++ C++;访问违规?
当我在linux中编码时,如果相同的代码像一个符咒一样工作,为什么我在这里得到一个访问冲突读取位置0xC0000005C++ C++;访问违规?,c++,access-violation,C++,Access Violation,当我在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(
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--;
}
void Arbol::VaciarAux(Nodo*&Nodo)
{
如果(nodo->izq!=NULL)
VaciarAux(nodo->izq);
如果(nodo->der!=NULL)
鱼子酱(nodo->der);
如果(nodo->izq==NULL&&nodo->der==NULL)
{
实际值=nodo;
nodo=NULL;
删除实际的;
康塔多--;
}
很可能是因为nodo
本身是无效指针。->
取消引用将导致问题
您需要检查可能影响该值的因素(缓冲区溢出导致损坏,由于某种原因设置为NULL)
请注意:
if (nodo->izq != NULL)
不检查nodo
变量是否为NULL,而是检查nodo
指向的izq
成员是否为NULL
如果如果nodo
本身为空,您只想什么都不做,那么可以在开始处输入:
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)
意味着如果树是空的,那么您将看到确切的问题,因为您尝试做的第一件事就是取消对空根节点的引用
更常见的方法是首先无条件地重复出现子节点(使用空保护器),然后处理节点本身,如:
def delTree (node):
if node == NULL:
return
delTree (node.left)
delTree (node.right)
delete node and whatever else you have to do
这将正确地处理一个空树,并且仍然正确地删除父树之前的所有子树。而且它看起来更优雅,这是首先使用递归的原因之一:-)
我将它留给读者作为一个练习,把它转回到C++。
你可能想看看你是如何创建<代码> Nodo < /C>类型(即,看看它的默认构造函数……它应该有一个,因为它是包含指针的类/结构)。。例如,如果您没有初始化Nodo
类型的成员,因此每当创建Nodo
对象时,两个指针成员最初都是NULL
,那么它们可能具有任何不确定的值,因此Arbol::VaciarAux
中的NULL
值测试将失败。例如在这种情况下,新的Nodo
将以初始化为某个随机值的指针结束,但Nodo
指针成员中包含的随机内存值不是内存中可访问的有效位置。然后,当您测试指针是否为NULL
时,测试结果为false,您将尝试取消引用它们在对Arbol::VaciarAux
的下一个递归调用中,导致访问冲突。正如pax所说,这可能是一个错误的指针。在Linux中,可能没有严格的虚拟内存规则,就像在其他地方运行代码一样(也取决于编译器)。因此,在Linux情况下,它可能会工作,但实际上可能会执行一些您不期望的操作。assert
仅用于程序的健全性检查。使用assert
执行的任何检查都不应出现在生产代码中。您可能在某处读取未初始化的内存,从而导致空检查通过,但随后您进入随机内存区域。但是,您应该发布更多代码来帮助评估您的问题。您的问题中没有足够的信息需要得到充分的答复。访问冲突可能是出于任何原因。您所说的“断言将起作用”是什么意思?提问时一定要非常具体。我在标题处将NULL定义为0。此函数是递归函数,它所做的是清理treeLinux具有严格的内存规则。然而,可能是在Linux上,他有一个有效的随机指针EAH,因为malloc是基于页面分配的,指针可以位于有效的页面边界内rict我的意思是,在Windows中,malloc调用的某些区域被标记为PROTECTED,因此在它们被释放后(在某些情况下)或在它们被mallocedso之前,您实际上无法使用它们。因此,用空根初始化树是一种不好的做法吗?不,这实际上是相当标准的-它是一个空树。我想我明白您现在的意思了(尽管有语言上的困难)-我会更新答案。如果(nodo->izq!=NULL)这是我决定跟随树枝的地方,我需要在这行中返回true或false,不管是左还是右。所以这是一个糟糕的做法,不知道他们为什么在university@paxdiablo问题:您提到了delTree(node.left)
没有将node.left
设置为NULL,但是由于他通过引用传递该指针,并且在删除节点时确实执行了node=NULL;
操作,这不应该影响node.left
的值吗?在上一个递归调用ended中,我正在使用默认构造函数模板的NULL值初始化它们类Nodo{public:Nodo(const-DNodo-datoPasado,Nodo*izqPasado=NULL,NULL-Nodo*derPasado=NULL):dato(datoPasado),izq(izqPasado),der(derPasado),equi(0){}Nodo();树中有多少个节点?这种访问冲突似乎是随机发生的,还是在一定数量的节点之后发生的?因为这是一种递归方法,我不应该问左或右子是否为NULL,这会导致访问冲突。我没有按照@paxdiablo的建议去做