Как освободить указатель без освобождения содержимого?

Я пытаюсь бороться с утечками памяти все больше и больше в своем стремлении выучить этот язык. Программа, над которой я работаю, это дерево двоичного поиска, корень дерева всегда находится в дереве - tree->root->l . Теперь, если я сделаю это ...

BSTNode *search(BSTree *tree ,Item elem)
{
    BSTNode* aux;
    aux = tree->root->l;

    /*
    *    BSTNode not found.
    *
    */    
    if(notFound)
    {
         free(aux);
         free(found)
         return NULL;
    }
 // . . . . . .
}

это также отменит дерево- tree->root->l ? как мне избежать этого, если так?

Всего 2 ответа


Сам указатель находится в автоматическом хранилище, что означает, что вам не нужно беспокоиться о его распределении или освобождении. Поэтому вам нужно беспокоиться не о указателе , а о памяти, адресуемой указателем. Это где free входит в игру. free не освобождает указатель, но память, к которой обращается указатель.

это также отменит дерево- tree->root->l ?

Это освободит память, на которую указывают aux и tree->root->l .

Эта память все еще используется деревом, поэтому она не должна быть освобождена в данный момент.

как мне избежать этого, если так?

Удалить free(aux); ,

Означает ли это, что если я оставлю такие переменные, это не вызовет утечку памяти или ненужное использование ресурсов?

Правильный. Вопрос, который вам нужно задать себе: «Адрес памяти, к которому обращается этот указатель, все еще используется?» Если ответ да, не освобождай его. Если ответ отрицательный, освободите его.


Да, tree->root->l будет освобожден, потому что aux указывает на ту же память. У вас есть два указателя, указывающие на одну и ту же область памяти. Передача любого указателя в free() освобождает память, на которую они оба указывают.

Вы избегаете этого, не передавая указатель free, указывающий на область памяти, которую вы не хотите освобождать.

Похоже, вы спрашиваете, как использовать aux чтобы указывать на что-то еще, не освобождая tree->root->l . Для этого вы можете просто переназначить aux :

aux = some_other_pointer;

Нет необходимости освобождать что-либо, пока вы сохраняете указатель, который все еще указывает на память, которую вам нужно будет освободить позже.

Из ваших комментариев: «У меня была идея, что вам нужно освободить все переменные, когда вы закончите с ними». Это почти правильно. Вы должны освободить всю динамически распределенную память. Вам не нужно пытаться освободить то, что вы не выделяли, с помощью вызова malloc , поэтому нет необходимости звонить free на aux . В какой-то момент вам нужно будет вызывать free для каждого элемента в двоичном дереве, но у вас все еще есть root указатель, чтобы отслеживать все это, и вы можете очистить его в конце программы или когда вам больше не нужно дерево.


Есть идеи?

10000