I am using Qt6, C 11, I declare two 2d arrays of dynamic sizes:
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:
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. Thank you very much
CodePudding user response:
The issue is that you can't guarantee that each call to new[]
will generate consecutive locations for the rows.
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
:
int A[MAX_ROWS * MAX_COLUMNS];
int B[MAX_ROWS * MAX_COLUMNS];
std::copy(&A[0], &B[0], MAX_ROWS * MAX_COLUMNS);
CodePudding user response:
You cannot use std::copy
to copy your array as a single chunk because you do not have a single array. What you have is a pointer to the first element of an array of pointers to the first element of arrays of int
s. That is, assuming rowCount
and colCount
are both 3, you have this:
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.
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. 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;
}