C 释放结构将得到0

C 释放结构将得到0,c,pointers,struct,C,Pointers,Struct,我有一段代码: struct nodo { char c; int val; struct nodo *pizq, *pder; }; typedef struct nodo NODO; 具有适当的初始值设定项功能: NODO * crea_nodo_int (int valor ) { NODO *p; p = (NODO *)malloc( sizeof( NODO ) ); if (p == NULL ) return N

我有一段代码:

struct nodo {
    char c;
    int val;
    struct nodo *pizq, *pder;
};
typedef struct nodo NODO;
具有适当的初始值设定项功能:

NODO * crea_nodo_int (int valor ) 
{
    NODO *p;
    p = (NODO *)malloc( sizeof( NODO ) );
    if (p == NULL )
        return NULL;
    p -> pizq = NULL;
    p -> pder = NULL;

    p -> val = valor;
    return p;
}
void inorder( NODO *p )
{
    if (p == NULL) return;

    if( p->pizq != NULL )
        inorder(( p->pizq );

    // Process root
    printf("%d ", p->val );

    if( p->pder != NULL )
        inorder( p->pder );
}
关于我的主要职能:

NODO * test = crea_nodo_int(5);
free(test);
inorder(test);
正如您所看到的,它是一个二叉树的实现,其中pizq和pder分别是左和右的子级

不过,我之所以发布这篇文章,是因为我知道“free()”实际上是释放内存的,我在这里看不到这一点。你看,我创建了值为5的节点测试,然后释放它,然后当我在控制台中按顺序行走时,它会打印出来 “0”并终止。为什么要打印0?如果(p==NULL)返回
并在不打印任何内容的情况下终止,是否应该直接转到
的情况?我做错了什么

以下是我的inorder函数代码:

NODO * crea_nodo_int (int valor ) 
{
    NODO *p;
    p = (NODO *)malloc( sizeof( NODO ) );
    if (p == NULL )
        return NULL;
    p -> pizq = NULL;
    p -> pder = NULL;

    p -> val = valor;
    return p;
}
void inorder( NODO *p )
{
    if (p == NULL) return;

    if( p->pizq != NULL )
        inorder(( p->pizq );

    // Process root
    printf("%d ", p->val );

    if( p->pder != NULL )
        inorder( p->pder );
}
free(ptr)
释放指针指向的内存
ptr
ptr
仍指向已释放的内存位置,访问此类内存是未定义的行为

检查

请注意,此(
free
)函数不会更改ptr本身的值,因此它仍然指向相同(现在无效)的位置

因此,只需调用
free()
将使指针成为一个不指向适当类型的有效对象的指针

调用
free(ptr)
后,按照将指针设置为
NULL

ptr = NULL;
这将防止指针出现悬空错误

所以,在你的情况下,你应该-

free(test);
test = NULL;
free(ptr)
释放指针指向的内存
ptr
ptr
仍指向已释放的内存位置,访问此类内存是未定义的行为

检查

请注意,此(
free
)函数不会更改ptr本身的值,因此它仍然指向相同(现在无效)的位置

因此,只需调用
free()
将使指针成为一个不指向适当类型的有效对象的指针

调用
free(ptr)
后,按照将指针设置为
NULL

ptr = NULL;
这将防止指针出现悬空错误

所以,在你的情况下,你应该-

free(test);
test = NULL;

一旦在某个指针上调用了
free
,就不允许在该内存区域上执行任何操作。因此,您不应该按顺序调用
(或者您可以在
free
之前调用它)

你的程序已经完成了。非常好。因此,它的行为是不可预测的,也无法解释(除非您花费数年时间深入研究实现细节)

我建议使用几个类似构造函数的函数:

NODE*create_leaf_node(int val);
NODE*create_pair_node(NODE*left, NODE*right);
并编写一个类似(递归)析构函数的函数(以调用
free(n);
结束):

当然,我想你有你的
结构nodo
,就像你的问题一样,并且

typedef struct nodo NODE;
您的测试程序可能会执行以下操作:

NODE*ntest = create_pair_node(create_pair_node(create_leaf_node(1),
                                               NULL),
                              create_leaf_node(3));
inorder(ntest);
destroy_node(ntest), ntest = NULL;
(我在最后一个语句中使用了)

然后用所有警告和调试信息编译程序(例如,
gcc-Wall-Wextra-g
with)。对其进行改进,使其不会收到警告使用调试器
gdb
(可能还有其他工具,如)


顺便说一句,在C。。。您可以考虑在“代码> MaloC/<代码>失败,然后退出程序时显示错误代码(如<代码> PrRor <代码> >),如

< P>一旦您在某个指针上调用了“代码>免费/代码>,就不允许在该内存区域做任何事情。因此,您不应该按顺序调用
(或者您可以在
free
之前调用它)

你的程序已经完成了。非常好。因此,它的行为是不可预测的,也无法解释(除非您花费数年时间深入研究实现细节)

我建议使用几个类似构造函数的函数:

NODE*create_leaf_node(int val);
NODE*create_pair_node(NODE*left, NODE*right);
并编写一个类似(递归)析构函数的函数(以调用
free(n);
结束):

当然,我想你有你的
结构nodo
,就像你的问题一样,并且

typedef struct nodo NODE;
您的测试程序可能会执行以下操作:

NODE*ntest = create_pair_node(create_pair_node(create_leaf_node(1),
                                               NULL),
                              create_leaf_node(3));
inorder(ntest);
destroy_node(ntest), ntest = NULL;
(我在最后一个语句中使用了)

然后用所有警告和调试信息编译程序(例如,
gcc-Wall-Wextra-g
with)。对其进行改进,使其不会收到警告使用调试器
gdb
(可能还有其他工具,如)


顺便说一句,在C。。。当代码< > MaloC/<代码>失败时,您可能会考虑显示(带有<代码> PrRor < /代码>)错误信息,然后退出程序,如

请阅读关于MulcLoTHOST的问题不完整。什么是
NODO
?@alk a struct…你没有一段代码。。。你有一个代码难题。请发送一个可测试和可编译的代码示例。。。。永远不要发送它的碎片(错误可能在其他地方)。请阅读关于铸造的信息。这个问题不完整。什么是
NODO
?@alk a struct…你没有一段代码。。。你有一个代码难题。请发送一个可测试和可编译的代码示例。。。。永远不要发送邮件(错误可能在其他地方),那么有没有办法做到这一点?我怎样才能避免我的有序行走实际上打印了一些东西?它将进入
printf(“%d”,p->val)行,这对我来说似乎很不自然。@DavidMerinos,请始终记住,C中函数的所有参数都是按值传递的,因此函数无法更改传递到
free(3)
,如果您不采取适当的措施,它将继续指向您已释放的位置。有没有办法做到这一点?我怎样才能避免我的有序行走实际上打印了一些东西?它将进入
printf(“%d”,p->val)行对我来说似乎不自然。@DavidMerinos,请始终记住,C中函数的所有参数都是按值传递的,因此函数无法更改传递到
free(3)
的指针,如果您不采取适当的措施,它将继续指向您已释放的位置。