0

ここでは、スタック上の要素を削除できるかどうかを確認する簡単なテストを行いました。

// This program test whether an object is dynamically allocated and passed as a parameter to a function , \
//free()ed in that function , then would it really get free()ed or still existing

#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
    int data ;
    struct node *next;
} node ;

void deleteElement(int *p)
{

    free(p);
}

void deleteNode(node *node)
{
    free(node);
}

int main()
{
    int i = 10 ;
    int *p = &i ;

    node *parent = (node *)malloc(sizeof(node));
    parent->data = 10;

    node *child = (node *)malloc(sizeof(node));
    parent->next = child ;

    deleteElement(p);
    printf("\np : %d",*p);

    deleteNode(parent);
    printf("\nparent node: %d",parent->data);
    printf("\nchild node : %d",child->data);
    return 0 ;
}

しかし、次のエラーが表示されます

codejack@ubuntu:~/Code::Blocks/ProgrammingTests$ ./a.out 
*** glibc detected *** ./a.out: free(): invalid pointer: 0x00007fff9e9fa284 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f34da65cb96]
./a.out[0x4005c4]
./a.out[0x400635]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f34da5ff76d]
./a.out[0x4004c9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 07:00 383254                             /home/codejack/Code::Blocks/ProgrammingTests/a.out
00600000-00601000 r--p 00000000 07:00 383254                             /home/codejack/Code::Blocks/ProgrammingTests/a.out
00601000-00602000 rw-p 00001000 07:00 383254                             /home/codejack/Code::Blocks/ProgrammingTests/a.out
0190a000-0192b000 rw-p 00000000 00:00 0                                  [heap]
7f34da3c8000-7f34da3dd000 r-xp 00000000 07:00 197806                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f34da3dd000-7f34da5dc000 ---p 00015000 07:00 197806                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f34da5dc000-7f34da5dd000 r--p 00014000 07:00 197806                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f34da5dd000-7f34da5de000 rw-p 00015000 07:00 197806                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f34da5de000-7f34da793000 r-xp 00000000 07:00 700468                     /lib/x86_64-linux-gnu/libc-2.15.so
7f34da793000-7f34da992000 ---p 001b5000 07:00 700468                     /lib/x86_64-linux-gnu/libc-2.15.so
7f34da992000-7f34da996000 r--p 001b4000 07:00 700468                     /lib/x86_64-linux-gnu/libc-2.15.so
7f34da996000-7f34da998000 rw-p 001b8000 07:00 700468                     /lib/x86_64-linux-gnu/libc-2.15.so
7f34da998000-7f34da99d000 rw-p 00000000 00:00 0 
7f34da99d000-7f34da9bf000 r-xp 00000000 07:00 700456                     /lib/x86_64-linux-gnu/ld-2.15.so
7f34daba5000-7f34daba8000 rw-p 00000000 00:00 0 
7f34dabbc000-7f34dabbf000 rw-p 00000000 00:00 0 
7f34dabbf000-7f34dabc0000 r--p 00022000 07:00 700456                     /lib/x86_64-linux-gnu/ld-2.15.so
7f34dabc0000-7f34dabc2000 rw-p 00023000 07:00 700456                     /lib/x86_64-linux-gnu/ld-2.15.so
7fff9e9db000-7fff9e9fc000 rw-p 00000000 00:00 0                          [stack]
7fff9e9ff000-7fff9ea00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)

実際、ツリーの削除を実装しているときに行き詰まりました。を使用して葉ノードを削除するfree()と、親が葉ノードになり、再帰を使用してそれらのノードも削除します。しかし問題は、リーフ ノードが実際には削除されず、まだそこにあることです。また、ツリーの削除で従った方法は次のとおりです

void deleteTree(struct node *root)
{
    if(root->left == NULL && root->right == NULL)
    {
       free(root);
    }
    else
    {
       if(root->left != NULL)
            deleteTree(root->left);
       if(root->right != NULL)
            deleteTree(root->right);
    }
}

このメソッドはリーフ ノードのみを削除し、対応する親ノードは削除されませんでした。XCodeでデバッグした後、リーフノードが削除されていないことがわかりました。それらはまだそこにありました。 では、なぜこのメソッドは、私が行ったテストのようにエラーを表示しませんか???

4

2 に答える 2

1

free()メモリが割り当てられていないポインタはできません。あなたの場合、有効なスタックのメモリを解放しようとしています。

void deleteElement(int *p)
{

    free(p);
}

int main()
{
    int i = 10 ;
    int *p = &i ;
    ....
    deleteElement(p);
    ...
}

deleteTree()メソッドでは、 ed の後に->leftor->rightを適切にリセットする必要があります。そうしないと、無効な/解放されたメモリにアクセスしようとします。free()

void deleteTree(struct node *root)
{
    if(root->left == NULL && root->right == NULL)
    {
       free(root);
    }
    else
    {
       if(root->left != NULL)
       {
            deleteTree(root->left);
            root->left = NULL;
       }
       if(root->right != NULL)
       {
            deleteTree(root->right);
            root->right = NULL;
       }
    }
}
于 2013-06-16T07:32:29.730 に答える
1

3 つの明らかなエラー:

(1)で割り当てられていないポインタをdeleteElement(p)呼び出すことになります。free()malloc()

(2) このコード:

deleteNode(parent);
printf("\nparent node: %d",parent->data);

parent削除された後の変数を参照します。

(3) ではdeleteTree()、子ノードを解放した後、非リーフ ノードを削除しないように、子ノードへの参照を保持します。

于 2013-06-16T08:51:17.823 に答える