如何使用指针C++将元素从2D数组复制到1D数组

How to you copy elements from a 2D array into a 1D array using pointers C++

本文关键字:数组 2D 复制 1D 元素 何使用 指针 C++      更新时间:2023-10-16

我有一个函数

double* get_row(double *the_array, int row_num, int col_size)    

其中,the_array是2D阵列,row_num是我要从中复制值的2D阵列上的行号,col_size是2D阵列的列大小。

功能实现

double* get_row(double *the_array, int row_num, int col_size) {
double* row = new double[col_size];
for (int i = 0; i < col_size; i++) {
*row = *(*(the_array + row_num) + i);
row++;
}
delete[] row;
return row;
}

我试图将值从2D数组the_array的行row_num复制到1D数组row,但编译器在行上给了我一个错误*row = *(*(the_array + row_num) + i);,我用它将元素从一个数组复制到另一个数组,完成这项任务的正确方法是什么。

顺便说一句,从visual studio获取的错误是:"*"的操作数必须是指针。

谢谢你的帮助。

为了解决这个问题,我假设"col_size"实际上是"列数"。并且数据按行主顺序排列。

则第N行的起始位置位于CCD_ 8处。

我将从这个助手功能开始:

inline double* view_row_n( double* array, int row, int num_cols ) {
return array+row*num_cols;
}

然后我会写一个复制缓冲区:

std::unique_ptr<double[]> copy_buffer( double const* in, int count ) {
double* retval = new double[count];
std::memcpy( retval, in, sizeof(double)*count );
return std::unique_ptr<double[]>( retval );
}

现在我会把它们一起使用:

double* get_row( double* the_array, int row_num, int col_size) {
auto retval = copy_buffer( view_row_n( the_array, row_num, col_size), col_size );
return retval.release();
}

我也会改变:

double* get_row( double const* the_array, int row_num, int col_size) {

甚至:

std::unique_ptr<double[]> get_row( double const* the_array, int row_num, int col_size) {

但这超出了你的问题范围。

如果get_row不需要将新内存分配回调用者,那么解决方案就是

double* get_row(double *the_array, int row_num, int col_size) 
{
return the_array + (row_num * col_size);
}

如果调用者期望为返回的行分配新的内存,那么

double* get_row(double *the_array, int row_num, int col_size) 
{
double* row = new double[col_size];
for(int i = 0; i < col_size; i++)
row[i] = *(the_array + (row_num * col_size) + i);
return row;
}

会起作用。

在第一个解决方案中,其想法是使用row_num * col_size到达正确的行,并简单地返回该地址位置作为结果。在第二个解决方案中,我们首先声明一个新行。然后使用i对该行中的每个单独元素进行索引,并从由the_array + (row_num * col_size)索引的该行的the_array复制每个元素。

这不是现代C++,显然不应该删除返回值。

im试图将2D数组的row_num行中的值复制到_array进入1D阵列

首先,the_array在本文中被定义为原始指针并用于指针运算,是2D数组的1D表示——在我们的描述中更准确。

获取[…]时的错误为:"*"的操作数必须是指针

好的,所以这行:

*row = *(*(the_array + row_num) + i);

有点乱。我想我知道你要怎么做了,但看,你无缘无故地两次取消引用(在表达式左侧使用*),这是BTW导致错误的原因。请记住,我们说过the_array原始指针,被视为1D数组。因此,您可以使用这种类型的指针算术,比方说在括号内,然后只取消引用一次。上面的表达式获取(the_array + row_num)的结果地址,取消引用它以获得数组的此单元格中的double,然后将i添加到double值本身,然后尝试取消引用doubleint i的和——这是double类型的临时变量。这可能是你的目标:

*row = *(the_array + row_num * col_size + i);

因为2D数据在存储器中被传染传播,逐行,连续,您需要将这样的行索引乘以行大小(这也是列数,我认为col_size实际上就是这样,否则您无法在行之间遍历)来"在行之间跳过">,最后添加当前单元格索引i以到达行内的特定单元格。然后,就像我们说的,取消整个事情。

除了编译问题和地址计算之外,在循环中递增row之前,您至少应该保留它的地址,这样您就可以返回它,而不是经过行末尾的指针为了尽可能多地保留您的原始函数,您可以使用第二个指针来完成它,如下所示:

double* get_row(double *the_array, int row_num, int col_size) {
double* row = new double[col_size];
double* rowPtr = row;
for (int i = 0; i < col_size; i++) {
*rowPtr = *(the_array + row_num * col_size + i);
rowPtr++;
}
return row;
}

我正在努力让它尽可能接近你的版本,这样你就可以看到与你所做的不同。很多事情都可以用不同的方式来做,例如为什么不像这个row[i] = *(the_array + row_num * col_size + i);一样首先使用[]运算符,然后完全去掉第二个指针?如果您按原样迭代i,则不需要在循环中的第二行执行++。另一个例子是您是否必须分配,或者您是否可以只返回一个指向现有数组的指针,但位置正确?

这里不需要提及的是,在几乎任何情况下,您都不应该像这样返回原始指针,因为这很容易导致代码中的意图不明确,即谁拥有分配(并负责最终删除分配),并提出了如何在出现异常时防止内存泄漏的问题?首选的解决方案是使用智能指针,如std::unique_ptr,它的一个实例封装原始指针并生成它,因此如果你想以不安全的方式丢弃那块内存,你必须非常明确。

double* get_row(double *the_array, int row_num, int col_size) {
double* row = new double[col_size];
for (auto i = 0; i < col_size; ++i) {
row[i] = the_array[row_num * col_size + i];
}
// If the return isn't assigned, the program will leak!
return row;
}
void row_test() {
double two_d[15];
const auto row = get_row(two_d, 2, 5);
// ...
// Be sure to delete row afterwards
delete[] row;
}