c - 释放内存导致的 Valgrind 错误?

标签 c valgrind

我遇到了这些 Valgrind 错误,但我真的不知道我做错了什么。我假设我正在使用指向空闲内存位置的指针。有帮助吗?

enter image description here

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

}

最佳答案

您自己捕获其中一些内容的一种方法是始终将您释放的任何指针清空,这样它就不会再有挥之不去的引用。

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 中变得更加积极,可以通过传递指针的 address 来释放内存,这样地址本身就可以在 来电者

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
}

如果你想使用这种技术,你真的必须全力以赴,因为指针地址参数通常会非常普遍,但永远不会有释放后使用错误是天赐之物。

编辑:释放后使用错误并不总是错误,有时它们是安全错误。

注意:在 C++ 中,您可以使用 ref 参数来提高可读性。

关于c - 释放内存导致的 Valgrind 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58598072/

相关文章:

c - 如何显示文本文件中与作为输入的前五个字符匹配的行?

c - WIN32 : Obtain Graphics Card Information?

c - 使用字符串方法在 C 中的 fizzbuzz 中出现错误?

c - Valgrind 给出错误 : "Conditional jump or move depends on uninitialised value(s)"

c++ - 查找 shared_ptr 的引用计数增加的位置

c++ - 为什么在一种情况下会发生内存泄漏,而在另一种情况下不会

c - 在 C 程序中使用 telnet

c - OpenSSL d2i_RSA_PUBKEY 导致段错误

c - 访问结构成员时 valgrind 出现无效读/写错误

c - 使用 free() 时大小为 4 的无效读取