簡體   English   中英

由於釋放 memory 導致的 Valgrind 錯誤?

[英]Valgrind errors due to freed memory?

我收到了這些 Valgrind 錯誤,但真的不知道我做錯了什么。 我假設我正在使用指向空閑 memory 位置的指針。 有什么幫助嗎?

在此處輸入圖像描述

Node* insertNode(Node *root, int value){

    if(!root) {
        root = malloc(sizeof(struct Node));
        root->data = value;
        root->left = root->right = NULL;
    }
    else if(value > root->data && root->right) {
        insertNode(root->right, value);
    }
    else if(value > root->data && !root->right) {
        root->right = insertNode(root->right, value);
    }
    else if(root->left) {
        insertNode(root->left, value);
    }
    else {
        root->left = insertNode(root->left, value);
    }

    return root;

}

Node* deleteNode(Node *root, int value) {

    if (root == NULL) 
        return root; 

    else if (value < root->data) {
        root->left = deleteNode(root->left, value); 
    }

    else if (value > root->data) {
        root->right = deleteNode(root->right, value); 
    }

    else if (root->left == NULL) { 
        Node *temp;
        temp = root->right; 
        free(root); 
        return temp; 
    } 

    else if (root->right == NULL) { 
        Node *temp;
        temp = root->left; 
        free(root); 
        return temp; 
        }  

    else {
        Node *temp;
        temp = smallestNode(root->right); 
        root->data = temp->data; 
        root->right = deleteNode(root->right, temp->data); 
    } 

    return root; 

}

Node* freeSubtree(Node *N) { if(!N) return;

    freeSubtree(N->left);
    free(N);
    freeSubtree(N->right);

}

自己捕獲其中一些內容的一種方法是,始終將 null 指向您已釋放的任何指針,這樣它就不會有揮之不去的引用。

Node* freeSubtree(Node *N) { if(!N) return;

  freeSubtree(N->left);

  free(N); N = NULL;          // NULL out the pointer!

  freeSubtree(N->right);
}

當然,@Johnny Mopp 已經指出了需要您將free()移到最后的實際錯誤。

在這樣的代碼的實踐中,我在 C 中變得更加激進,任何 function 可能會通過傳遞指針的地址來釋放 memory,因此地址本身可以被傳入調用者

Node *freeSubtree(Node **PN)
{
  if (!PN  ||  !*PN) return;

  freeSubtree( &( (*PN)->left) );   // frees and NULLs the ->left pointer
  freeSubtree( &( (*PN)->right) );  // frees and NULLs the ->right pointer

  free(*PN);
  *PN = NULL;  // NULL the *caller's* handle on the pointer
}

如果你想使用這種技術,你真的必須全押 go 因為指針地址參數通常非常普遍,但永遠不會有釋放后使用錯誤是天賜之物。

編輯:釋放后使用錯誤並不總是錯誤,有時它們是安全錯誤。

注意:在 C++ 中,您可以使用 ref 參數來提高可讀性。

暫無
暫無

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

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