如果我在 C++ 中删除一次数组,但多次分配它怎么办?

What if I delete an array once in C++, but allocate it multiple times?

假设我有以下片段。

int main()
{
    int num;
    int* cost;
    while(cin >> num)
    {
        int sum = 0;
        if (num == 0)
          break;

        // Dynamically allocate the array and set to all zeros
        cost = new int [num];
        memset(cost, 0, num);
        for (int i = 0; i < num; i++)
        {
            cin >> cost[i];
            sum += cost[i];
        }
        cout << sum/num;
    }
`  `delete[] cost;
    return 0;
}

尽管我可以在 while 循环中移动 delete 语句 对于我的代码,出于理解的目的,我想知道代码在编写时会发生什么。每次使用运算符new时,C++是否分配不同的内存空间?

operator delete 是否仅删除分配给 cost 数组的 last

每次为数组分配新内存时,之前分配的内存都会泄漏。根据经验,您需要释放内存的次数与分配的次数一样多。

是的。因此,除了最后一次之外,循环的每次迭代都会发生内存泄漏。

当您使用 new 时,您分配了一块新的内存。将 new 的结果分配给一个指针只会改变这个指针指向的内容。它不会自动释放此指针之前引用的内存(如果有的话)。

Does C++ allocate different memory spaces each time I use operator new?

是的。

Does operator delete only delete the last allocated cost array?

是的。

您丢失了指向其他人的唯一指针,因此它们不可逆转地泄露了。为了避免这个问题,不要玩弄指针,而是使用 RAII 来自动管理动态资源。 std::vector 在这里是完美的(如果你真的需要一个数组;你的例子可以继续阅读并重新使用一个 int)。

第一行错的是:

memset(cost, 0, num);

它假设一个整数只有一个字符长。更典型的是四个。如果你想使用 memset 来初始化数组,你应该使用这样的东西:

memset(cost, 0, num*sizeof(*cost));

或者更好的是转储 memset 并在分配内存时使用它:

cost = new int[num]();

正如其他人所指出的,delete 放置不正确,将泄漏由其相应的 new 分配的所有内存,除了最后一个。将其移动到循环中。

您的代码中没有 cost 数组。在您的代码中 cost 是一个 指针 ,而不是一个数组。

您代码中的实际 数组 是通过重复 new int [num] 调用创建的。每次调用 new 都会创建一个新的、独立的 nameless 数组对象,该对象位于动态内存中的某个位置。新数组一旦由 new[] 创建,就可以通过 cost 指针访问。由于数组是 nameless,因此 cost 指针是 only link 导致创建的无名数组通过 new[]。您没有其他方法可以访问该无名数组。

每次你在你的循环中这样做 cost = new int [num],你就在创建一个全新的、不同的数组,将 link 从 cost 打破到前一个数组并使 cost指向新的。

由于 cost 是您对旧数组的唯一 link,旧数组将无法访问。对那个旧数组的访问将永远丢失。它变成了内存泄漏。

正如您自己正确陈述的那样,您的 delete[] 表达式仅取消分配最后一个数组 - cost 最后指向的数组。当然,只有当您的代码执行了 cost = new int [num] 行时,这才是正确的。请注意,您的循环可能会在不进行单个分配的情况下终止,在这种情况下,您将 delete[] 应用于未初始化(垃圾)指针。

强烈建议您不要在C++程序中使用"C idioms"。让 std 图书馆 你工作:这就是它存在的原因。如果你想要 "an array (vector) of n integers," 那么这就是 std::vector 的全部内容, 它 "comes with batteries included." 不要不必对 "setting a maximum size" 或 "setting it to zero." 之类的事情胡闹 你只需与 "this thing," 一起工作,你不必 [必须...] 关心其内部运作, 知道它已经经过彻底的设计和测试。

此外,当您这样做时,您是在 C++ 现有的内存管理框架内工作。特别是,您没有在自己的应用程序中执行任何操作 "out-of-band" "that the standard library doesn't know about, and which might (!!) it up."

C++ 为您提供了一个非常全面的库,其中包含快速、高效、健壮、经过良好测试的功能。 利用它。