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)
的指针,如果您不采取适当的措施,它将继续指向您已释放的位置。