5

我正在查看“Programming Interviews Exposed”一书中的以下代码:

bool deleteStack( Element **stack ){
      Element *next;
      while( *stack ){
            next = (*stack)->next;
            free( *stack );
            *stack = next;
      }
      return true;
}

我对 C++ 或 C 不是很熟悉,所以这可能是一个愚蠢的问题,但是在释放指针后不会给指针赋值会导致问题吗?

4

4 回答 4

8

在您的示例中,*stack是一个指针。释放它指向的内存然后将指针分配给一个新变量是非常安全的。

唯一不安全的就是*stack在释放它之后取消引用。

free( *stack );
next = (*stack)->next;

将是不正确的,因为调用后指向的内存*stack具有不可预测的内容(甚至可能不再可供您的进程访问)free

于 2013-01-21T16:47:26.630 回答
4

没关系。您实际上并没有“释放指针”这样做:

 free( *stack );

但是您释放了指针指向的一些动态分配的内存*stack。当你这样做时:

*stack = next;

您使指针指向不同的内存块,仅此而已。

于 2013-01-21T16:49:11.250 回答
1

这样做是安全的。当你看到类似的东西时,(*stack)你可以把它想象成“堆栈指向”。由于free期望指向内存位置的指针,因此您正在从进程虚拟内存中释放堆栈指向的“内存插槽”。这意味着内存地址(即指针)的空间仍然可用,您可以重新使用它。
另外,我认为这可能很有用,当您使用箭头符号时,->您在 C/C++ 中使用了两种不同的符号,简化了它的常用用途。所以,这:stack->next与此相同:(*stack).next 祝你好运。

于 2013-01-21T16:56:56.813 回答
1

释放后分配NULL给指针变量只是为了在代码中保留一个提示,以识别释放的地址是否发生取消引用。

如果我们不将 NULL 分配给已释放的指针,则如果我们取消对已释放指针变量的引用,则行为是未定义的(崩溃的 50% 机会和堆损坏的剩余机会)。但是如果NULL设置它肯定会崩溃。如果堆损坏,则很难识别错误而不是在一个地方崩溃。

请不要认为释放的指针永远不会在您的代码中被取消。如果一个项目维护了很长时间,那么就有可能错误地添加(或修改)代码。

于 2013-01-21T18:24:03.403 回答