简体   繁体   English

我可以使用 std::copy 复制堆上分配的数组吗?

[英]Can I use std::copy to copy arrays allocated on heap?

I am using Qt6, C++ 11, I declare two 2d arrays of dynamic sizes:我正在使用 Qt6、C++ 11,我声明了两个动态大小的二维数组:

int **A; int **B;
A = new int*[rowCount]();
for(int i = 0; i < rowCount; i++)
{
    A[i] = new int[colCount]();   //Same for B
}
// Then feed A with some incoming values

and I want to copy all A's values to B, I know that using std::copy is faster and cleaner than using for -loop, so I tried:我想将所有 A 的值复制到 B,我知道使用 std::copy 比使用 for -loop 更快更干净,所以我尝试了:

 std::copy(&A[0][0], &A[0][0]+rowCount*colCount,&B[0][0]);

However I got error message:但是我收到错误消息:

code: 0xc0000005: read access violation at: 0x0, flags=0x0 (first chance)

Looks like I am trying to access memories not allocated?看起来我正在尝试访问未分配的内存? But I have already allocated two arrays on the heap但是我已经在堆上分配了两个数组

Why I don't use 2d vector or list is that I need to process large amount of data and accessing array by index is O(1), if you think this is caused by my compiler I can provide make file and project file snippets.为什么我不使用 2d 向量或列表是因为我需要处理大量数据并且按索引访问数组是 O(1),如果您认为这是由我的编译器引起的,我可以提供 make 文件和项目文件片段。 Thank you very much非常感谢

Edit: @Miles Budnek pointed out that std::vector and raw C++ array have similar indexing performances (both O(1)).编辑: @Miles Budnek 指出 std::vector 和原始 C++ 数组具有相似的索引性能(均为 O(1))。 I am handing large amount of data, the way I store and read data is basically indexing.我正在处理大量数据,我存储和读取数据的方式基本上是索引。

I have tested std::vector and C++ array indexing performances under MSVC 2019 64-bit, C++ 11 using Qt creator and I found they are similar(std::vector even a little bit faster), if under most environments(like various compilers) std::vector and raw C++ array are both O(1), I would say std::vector is safer and more convenient than C++ raw arrays.我已经使用 Qt creator 在 MSVC 2019 64 位、C++ 11 下测试了 std::vector 和 C++ 数组索引性能,我发现它们是相似的(std::vector 甚至更快一点),如果在大多数环境下(如各种编译器) ) std::vector 和原始 C++ 数组都是 O(1),我想说 std::vector 比 C++ 原始数组更安全、更方便。

But it looks like QVector indexing speed is much lower?但看起来 QVector 索引速度要低得多?

The issue is that you can't guarantee that each call to new[] will generate consecutive locations for the rows.问题是您不能保证每次调用new[]都会为行生成连续的位置。

Your 2d array is actually a 1d array of pointers to random memory locations .您的二维数组实际上是指向随机内存位置的一维数组。 There is no guarantee that the beginning of one row follows the end of the previous row.不能保证一行的开头跟在前一行的结尾之后。

So, to copy your 2d array, you'll have to loop through the rows, copying each row separately:因此,要复制二维数组,您必须遍历行,分别复制每一行:

for (int row = 0; row < rowCount; ++row)
{
    std::copy(&A[row], &B[row], colCount);
}

If you allocate the 2d array at contiguous locations, you could then use one call to std::copy :如果您在连续位置分配二维数组,则可以使用一次调用std::copy

int A[MAX_ROWS * MAX_COLUMNS];
int B[MAX_ROWS * MAX_COLUMNS];
std::copy(&A[0], &B[0], MAX_ROWS * MAX_COLUMNS);

You cannot use std::copy to copy your array as a single chunk because you do not have a single array.您不能使用std::copy将数组复制为单个块,因为您没有单个数组。 What you have is a pointer to the first element of an array of pointers to the first element of arrays of int s.您所拥有的是指向指向int数组的第一个元素的指针数组的第一个元素的指针。 That is, assuming rowCount and colCount are both 3, you have this:也就是说,假设rowCountcolCount都是 3,你有这个:

A
┌───┐
│   │
│ │ │
│ │ │
└─┼─┘
  │
  ▼
┌───┐
│   │        ┌───┬───┬───┐
│ ──┼───────►│ 0 │ 0 │ 0 │
│   │        └───┴───┴───┘
├───┤
│   │        ┌───┬───┬───┐
│ ──┼───────►│ 0 │ 0 │ 0 │
│   │        └───┴───┴───┘
├───┤
│   │        ┌───┬───┬───┐
│ ──┼───────►│ 0 │ 0 │ 0 │
│   │        └───┴───┴───┘
└───┘

As you can see, there is no contiguous chunk of elements for std::copy to copy.如您所见, std::copy没有连续的元素块来复制。

If you want to be able to efficiently copy (and access) elements of your array, you should allocate a single array that is rowCount*colCount long.如果您希望能够有效地复制(和访问)数组的元素,您应该分配一个rowCount*colCount长的数组。 If you want nice syntax you could wrap it up in a class and overload the () or [] operator to make the access nicer.如果你想要好的语法,你可以将它包装在一个类中并重载()[]运算符以使访问更好。 For example:例如:

class Matrix
{
private:
    int rowSize_;
    std::vector<int> storage_;
public:
    Matrix(int rowCount, int colCount)
         : rowSize_{colCount},
           storage_(rowCount * colCount)
    {}

    int& operator()(int row, int col)
    {
        return storage_[row * rowSize_ + col];
    }
};

int main()
{
    Matrix mat{3, 3};
    mat(1, 2) = 42;

    // copy with simple copy construction
    Matrix mat2 = mat;

    // or copy-assignment
    mat2 = mat;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM