簡體   English   中英

C ++訪問沖突?

[英]C++ Access violation?

為什么我在這里獲取訪問沖突讀取位置0xC0000005如果在linux中編碼時相同的代碼就像魅力一樣?

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--;
    }

很可能是因為nodo本身是一個無效的指針。 ->解除引用會導致問題。

您需要檢查可能影響該值的事物(緩沖區溢出導致損壞,由於某種原因設置為NULL)。

注意:

if (nodo->izq != NULL)

檢查nodo變量為NULL,而是如果izq了會員nodo點為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 ++。

正如pax所說,它可能是一個糟糕的指針。 在Linux中,可能沒有像在其他地方運行代碼那樣嚴格的虛擬內存規則(也取決於編譯器)。 所以在Linux的情況下,它可能正在工作,但實際上可能正在做一些你不期望的事情。

您可能想要了解如何創建Nodo類型(即,查看其默認構造函數......它應該有一個,因為它是包含指針的類/結構)。 例如,如果你沒有初始化Nodo類型的成員,那么每當創建Nodo對象時,兩個指針成員最初都是NULL ,那么它們可以具有任何不確定的值,以便在Arbol<T>::VaciarAux測試NULLArbol<T>::VaciarAux將失敗。 例如,新的Nodo最終會將指針初始化為某個隨機值,但Nodo指針成員中包含的那些隨機內存值不是內存中可訪問的有效位置。 然后,當您測試指針是否為NULL ,測試結果為false,並且您嘗試在下一次對Arbol<T>::VaciarAux遞歸調用中取消引用它們,從而導致訪問沖突。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM