这段代码是否安全(为什么它没有崩溃)?

时间:2017-10-31 17:01:43

标签: c++ c

我看到了列表合并排序的解决方案:

struct Node* SortedMerge(struct Node* a, struct Node* b)
{
  struct Node* result = NULL;

  /* Base cases */
  if (a == NULL)
     return(b);
  else if (b==NULL)
     return(a);

  /* Pick either a or b, and recur */
  if (a->data <= b->data)
  {
     result = a;
     result->next = SortedMerge(a->next, b);
  }
  else
  {
     result = b;
     result->next = SortedMerge(a, b->next);
  }
  return(result);
}

似乎它不安全,因为struct Node* result在堆栈上分配,并且在从函数调用返回后需要是空闲的。

我检查了它的确有效(没有崩溃)。

代码安全吗?为什么?

3 个答案:

答案 0 :(得分:5)

只要您不动态分配它,您就不负责解除分配。我不明白为什么这会因为它在stack上而失败。

这不会导致错误。

如果你在每次调用函数时分配结果然后不释放它会很糟糕,因为这会导致内存泄漏。

如果您尝试从函数返回局部变量的地址,那么也会出错。

答案 1 :(得分:1)

如果你担心递归会破坏堆栈,那么你是对的;在大多数情况下,最大堆栈大小是有限的(例如,在Windows x64上默认为1MB)。

所以你可以在打击堆栈之前最多递归大约32767次(假设至少还需要将返回地址存储在堆栈中)。

这就是为什么你应该避免对用户提供的数据进行递归而更喜欢迭代。

答案 2 :(得分:0)

不完全,只有变量结果在堆栈中分配,但实际内存仍然在堆中,堆栈中分配了更多的内容

 struct Node* result = NULL;

下面这些语句只是指向由指针a或b指向的内存或由SortedMerge()返回的内存的指针;

result = a;
result->next = SortedMerge(a->next, b);
result = b;
result->next = SortedMerge(a, b->next);

并且这些可能在堆中或由被调用函数的本地分配的内存中分配,在这种情况下,只要存在调用函数作用域,内存仍然存在。

返回局部变量的地址是一个错误,但是局部变量的传递地址被认为是完全正常的。