我正在查看“编程访谈曝光”一书中的以下代码:
bool deleteStack( Element **stack ){
Element *next;
while( *stack ){
next = (*stack)->next;
free( *stack );
*stack = next;
}
return true;
}
我对C ++或C不太熟悉,所以这可能是一个愚蠢的问题,但是在释放它之后不会给指针分配一些东西导致问题?
答案 0 :(得分:8)
在您的示例中,*stack
是一个指针。释放它指向的内存然后将指针分配给一个新变量是完全安全的。
唯一不安全的事情就是在释放后取消引用*stack
。
free( *stack );
next = (*stack)->next;
是不正确的,因为*stack
调用的内存在free
调用后具有不可预测的内容(甚至可能无法访问您的进程)。
答案 1 :(得分:4)
不,没关系。你实际上并没有“释放指针”这样做:
free( *stack );
但是释放指针*stack
指向的一些动态分配的内存。当你这样做时:
*stack = next;
你使指针指向不同的内存块,就是这样。
答案 2 :(得分:1)
这样做是安全的。当你看到像(*stack)
这样的东西时,你可以把它想象成堆栈指向的那样。由于free
期望指向内存位置的指针,因此您可以释放内存插槽'从进程虚拟内存中指向堆栈。
这意味着内存地址(即指针)的空间仍然可用,您可以重复使用它
此外,我认为这可能很有用,当您使用箭头符号->
时,您会在C / C ++中使用两种不同的符号来简化其常用用法。所以,这个:stack->next
与此相同:(*stack).next
祝好运。
答案 3 :(得分:1)
在释放它之后将NULL
分配给指针变量只是为了在代码中保留一个提示,以识别释放的地址是否发生了取消引用。
如果我们不为释放的指针分配NULL,则行为是未定义的(如果我们解除释放的指针变量,则50%的崩溃几率和剩余的堆损坏机会)。但如果NULL
设置它肯定会崩溃。如果堆被破坏,那么很难识别出错误,而不是在一个地方崩溃。
请不要认为释放的指针永远不会在代码中被取消。如果项目保持很长时间,那么就有可能错误地添加(或修改)代码。