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

时间:2015-05-20 14:11:26

标签: c++ arrays memory memory-management new-operator

假设我有以下代码段。

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 ++是否会分配不同的内存空间?

运营商delete是否仅删除最后分配的cost数组?

6 个答案:

答案 0 :(得分:22)

  

每次使用operator new时,C ++是否会分配不同的内存空间?

  

运营商delete是否仅删除最后分配的cost数组?

是。

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

答案 1 :(得分:7)

强烈建议你不要使用&#34; C成语&#34;在 C ++ 程序中。让std图书馆你工作:这就是为什么它在那里。如果你想要&#34; n 整数的数组(向量),&#34;那就是std::vector的全部内容,它&#34;附带电池。&#34; 不必喋喋不休地使用&#34;设置最大尺寸&#34;或&#34;将其设置为零。&#34;你只需使用&#34;这个的东西,&#34; ,你的内部工作你不必[关心...]关心,知道它已经经过彻底的设计和测试。< / p>

此外,当您这样做时,您将在C ++的现有内存管理框架内工作。特别是,你没有做任何事情&#34;带外&#34;在你自己的应用程序中#34;标准库不知道,哪些可能(!!)它。&#34;

C ++为您提供了一个非常全面的快速,高效,强大且经过良好测试的功能库。 利用它。

答案 2 :(得分:5)

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

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

每次在你的周期中执行cost = new int [num]时,你就会创建一个全新的,不同的数组,打破从cost到前一个数组的链接并使cost指向新的。

由于cost是您唯一的旧数组链接,因此旧数组无法访问。永远丢失对旧阵列的访问权限。它变成了内存泄漏。

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

答案 3 :(得分:3)

是。因此,除了最后一次迭代之外,每次迭代都会出现内存泄漏。

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

答案 4 :(得分:3)

首先关闭这一行是错误的:

memset(cost, 0, num);

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

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

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

cost = new int[num]();

正如其他人指出的那样,删除被错误地放置并且将泄漏由其相应的新分配的所有内存,除了最后一个。把它移到循环中。

答案 5 :(得分:1)

每次为阵列分配新内存时,先前分配的内存都会泄露。根据经验,您需要释放内存的次数与分配的次数相同。