从一个动态分配的数组复制到另一个数组 C++

8

这似乎应该有一个超级简单的解决方案,但我就是想不出来。我只是创建了一个调整大小的数组,尝试将所有原始值复制过来,最后删除旧数组以释放内存。

void ResizeArray(int *orig, int size) {
    int *resized = new int[size * 2]; 
    for (int i = 0; i < size; i ++)
        resized[i] = orig[i];
    delete [] orig;
    orig = resized;
}

这里似乎出现了一个问题,即resized[i] = orig[i]通过引用而非值来复制值,因此在对orig进行操作后打印时返回一些垃圾值,除非我注释掉delete [] orig。我该如何从orig制作深层副本以供resized使用,或者我面临的是其他问题?我不想使用std::vector。

请注意,不存在“按引用复制值”的概念。你要么是创建对相同数据的新引用,要么是进行复制。 - André Caron
2
即使您不想使用 std::vector,将其封装在一个类中,以便客户端可以传递不变的对象,而不必管理实现指针随每次调整大小而改变的事实,这样您也会受益匪浅。 :-/ - HostileFork says dont trust SE
作为一种优化,你可以使用memcpy来复制数组内容。我在godbolt上进行了检查,无论是gcc还是clang都没有用memcpy替换复制循环(我以为他们现在有时会这样做,但这里没有)。 - undefined
4个回答

14

记住,在C++中,参数是按值传递的。你正在将resized分配给传递给你的指针的副本,函数外部的指针保持不变。

您应该使用双重间接性(或“双指针”即指向指向int的指针):

void ResizeArray(int **orig, int size) {
    int *resized = new int[size * 2]; 
    for (int i = 0; i < size; i ++)
        resized[i] = (*orig)[i];
    delete [] *orig;
    *orig = resized;
}

或指向指针的引用:

void ResizeArray(int *&orig, int size) {
    int *resized = new int[size * 2]; 
    for (int i = 0; i < size; i ++)
        resized[i] = orig[i];
    delete [] orig;
    orig = resized;
}

顺便提一句,对于数组大小,你应该使用 <cstddef> 中的类型 std::size_t - 它保证可以容纳任何对象的大小,并且清楚地表明我们正在处理一个对象的大小。


1
另一个选项是使用返回值返回新数组。 - André Caron
@AndréCaron:那也是一个选择,但我认为这些表单更适合缩进使用。 - Matteo Italia
作为澄清,回答者所说的“double pointer”指的是“double indirection”。当我第一次读到时,我很困惑他为什么想用double *替换int * - Michael Price

3
我强烈建议使用std::vector<int>代替数组。这种数据结构会根据需要进行调整大小,并且已经经过了调整大小的测试。

虽然“向量”通常是一些有趣的东西,但也存在着各种反对它们的理由。因此,你的回答是基于观点而不是针对 OP 问题的实际回答。 - Markus
@Markus:关于数组也可以这样说。存在许多反对它们的理由,因此OP的问题是基于观点的,应该被关闭(或者删除)。 - Thomas Matthews

2

orig 必须是一个指向指针的指针,才能将其赋值给 resized

int **orig;
*orig = resized;

0
我正在复制一个动态数组。
    #include <iostream>

    void FillArray(int* const arr, const int size)
    {
       for(int i = 0; i < size; i++)
       {
           arr[i] = rand() % 10;
       }
    }

    void ShowArray(int* const arr, const int size)
    {
        for(int i = 0; i < size; i++)
        {
            std::cout << arr[i] << '\t';
        }
        std::cout << std::endl;
    }

    int main()
    {
        int size = 10;
        int *arr1 = new int [size];
        int *arr2 = new int [size];

        FillArray(arr1, size);
        FillArray(arr2, size);

        std::cout << "arr1 = ";
        ShowArray(arr1, size);
        std::cout << "arr2 = ";
        ShowArray(arr2, size);

        delete [] arr1;
        arr1 = new int [size];
        for(int i = 0; i < size; i++)
        {
            arr1[i] = arr2[i];
        }

        std::cout << "==========================" << std::endl;

        std::cout << "arr1 = ";
        ShowArray(arr1, size);
        std::cout << "arr2 = ";
        ShowArray(arr2, size);

        delete [] arr1;
        delete [] arr2;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接