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



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

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是在堆栈上分配的,并且在从函数调用返回后需要空闲。

我检查了一下,它可以工作(没有崩溃)。

那么代码安全吗?为什么?

只要你不是动态分配它,你就没有责任去分配它。我不明白为什么这会失败,因为它在stack.

这不会导致错误。

如果您在每次调用函数时分配结果,然后不释放它,那将是不好的,因为这会导致内存泄漏。

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

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

因此,在吹取堆栈之前,您最多可以递归大约 32767 次(假设至少返回地址也需要存储在堆栈上)。

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

不完全是,只有变量结果在堆栈中分配,但实际内存仍在堆中,堆栈中没有分配任何东西

 struct Node* result = NULL;

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

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

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

返回局部变量的地址

是一个错误,但是传递局部变量的地址被认为是完全可以的。

相关内容

最新更新