【问题标题】:new and delete on different scope在不同的范围内新建和删除
【发布时间】:2016-02-01 23:51:40
【问题描述】:

考虑以下代码:

int *expand_array(int *old_arr,int array_length)
{
    int *new_arr = new int[array_length +3];
    for(int counter=0;counter<array_length;counter++)
    new_arr[counter]=old_arr[counter];

    delete[] old_arr;
    return new_arr;
}

int main()
{
     int *my_first_arr = new int[4];
     int *my_expanded_arr=expand_array(my_first_arr,4);
     delete[] my_expanded_arr;
 }

这里会有内存泄漏吗? 为了概括这个问题, 如果从新语句返回的指针被复制,传递给函数或分配给不同的指针,删除复制指针会释放内存吗?

【问题讨论】:

    标签: c++ c++11 visual-c++ c++14


    【解决方案1】:

    您的代码是完全有效的 C++,并且没有内存泄漏。您可以随意复制指针,deleteing 任何范围内的任何副本都具有相同的效果。

    但是,这仍然是一种不好的做法,您不应该编写这样的代码。使用原始的new 和delete 太容易出错,并且会导致难以维护的代码。相反,请使用 RAII 包装器类型,如 std::unique_ptr、std::shared_ptr 或在本例中为 std::vector。

    你问题中的代码基本上是这样的。

    int
    main()
    {
      auto numbers = std::vector<int>(4);
      numbers.resize(7);
    }
    

    很简单,不是吗?

    【讨论】:

    • "你的代码是完全有效的 C++ 并且没有内存泄漏。" 如果new int[array_length +3]; 抛出,那么my_first_arr 肯定会泄漏,不是吗?
    • 它会“泄漏”,但在这种情况下,程序无论如何都会被终止。但确实,代码不能以异常安全的方式编写。
    【解决方案2】:

    为什么你认为会有内存泄漏?当然不会。

    但是这段代码有一个不同的错误。如果新数组大小大于现有old_arr 的大小,则将旧数组复制到新分配的int 数组的代码将复制太多,跑过旧数组的末尾,导致在未定义的行为中;可能会崩溃(旧数组大小为 2 个整数,array_length 为 10,for 循环将尝试从只有 2 个的旧数组中复制 10 个值)。

    【讨论】:

    • 我不认为“当然”是对代码审查请求的有用回应。虽然这样的请求是否是主题是另一回事。
    • 谢谢。我怀疑 delete 需要从 new 返回的原始指针 - 并且只有那个 - 才能删除动态分配的内存。在继续复制代码之前,可能会检查数组大小。
    • @ParakmiI `delete 的行为类似于一个按值获取参数的函数。它只关心你传递给它的值和类型。
    猜你喜欢
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    相关资源
    最近更新 更多