4

问题:在变量n的什么值下,以下代码会导致内存泄漏?

那是代码:


int* Bar(int n)
{
  if (n == 1)
    throw "exception";
  return new int[n];
}

void Foo(int n)
{
  int *a = Bar(n);
  if (n <= 2)
    return;
  delete[] a;
}

从 5.3.4/7

当 direct-new-declarator 中表达式的值为零时,调用分配函数来分配一个没有元素的数组。

从 3.7.3.1/2

取消引用作为零大小请求返回的指针的效果是未定义的。

即使 [by new] 请求的空间大小为零,请求也可能失败。

这意味着您可以这样做,但是您不能合法地(以在所有平台上以明确定义的方式)取消引用您获得的内存-您只能将其传递给数组删除-您应该删除它。

这是一个有趣的脚注(即不是标准的规范部分,但包括用于说明目的)附加到 3.7.3.1/2 的句子中

[32. 目的是通过调用 malloc() 或 calloc() 来实现 operator new(),因此规则基本相同。C++ 与 C 的不同之处在于要求零请求以返回非空指针。]

  • 如果 n 为 1,我们得到:

int *a = Bar(1) 和 Bar(1) 抛出异常。它会是变量a的构造函数中的异常吗?它会导致内存泄漏吗?

4

6 回答 6

7

如果 a == 0 或 a == 2,它可能会导致它们。

如果 a == 1 抛出异常并且没有分配内存。如果 a > 2 内存被分配和释放。

如果 a == 0 必须分配内存,因为不允许 new 返回空指针。您必须使用 delete[] 释放分配的内存。

如果分配了 a == 2 内存并且函数返回。这是一个明显的泄漏。

于 2009-07-16T11:04:25.067 回答
2
如果 n < 0 你将更有可能得到异常 std::bad_alloc (因为 n 将被转换为无符号的 size_t ) - 没有内存泄漏。
如果 n == 1 你会得到异常(由`throw "exception"`调用)——没有内存泄漏。
如果 n == 0 || n == 2 你永远不会调用 delete - 内存泄漏。
如果 n > 2 你会调用 delete - 没有内存泄漏。
于 2009-07-16T11:18:38.080 回答
0

不,如果我正确理解您的问题,bar 函数将抛出异常,而 Foo 函数实际上从未捕获它,这意味着它也会从该函数中传递出去。但是不,它不应该导致内存泄漏,因为你在分配之前就抛出了。

于 2009-07-16T11:06:16.403 回答
0

您的评估大部分是正确的 - n = 2 会导致内存泄漏,n = 0 理论上会导致内存泄漏 - n = 1 会引发异常(因此永远不会执行 new int),因此不会发生内存泄漏。

n > 2 的任何值都不会导致内存泄漏。

现在如果 n < 0 - 你有未定义的行为 - 你可能会出现内存泄漏(即负 int 可以转换为大的正无符号值 - 可能会发生坏事)

于 2009-07-16T11:14:24.547 回答
0

由于抛出的异常没有捕获器,它将继续进行并返回。但是由于我们声明为整数指针,如果您将“n”作为零发送,则会创建一个默认指针。您也可以检查指针的大小。但这不会导致任何内存泄漏。背后的原因,当你做一个返回时,因为它是一个整数指针并且是一个局部变量,默认情况下会释放所占用的内存。因此,在您提到的情况下不会发生内存泄漏。

于 2009-07-16T11:14:50.350 回答
0

是的,02会得到内存泄漏。


这也是管理动态内存的非常糟糕的做法。在 C++ 上,创建一个管理内存的类是更自然/更好的方法(例如,在构造函数中它分配一些内存,而在析构函数中它释放它)。这将更无泄漏和更安全

于 2016-08-15T13:37:02.253 回答