指向 C++ 中动态分配的二维数组中的一行的指针
Posted
技术标签:
【中文标题】指向 C++ 中动态分配的二维数组中的一行的指针【英文标题】:Pointer to one row in dynamically allocated 2D array in C++ 【发布时间】:2016-07-25 19:43:17 【问题描述】:我有一个动态分配的二维数组 Volatility[r][c] 在 C++ 中具有 r 行和 c 列。是否可以以某种方式创建指向某个列 c1 的指针 ptrColumn,以便我可以使用 ptrColumn[r1] 访问元素 (r1,c1)? 到目前为止,我尝试创建动态指针。但我没能做到。 谢谢!
【问题讨论】:
“动态分配的二维数组”在 C++ 中不是一个定义明确的术语。至少有两种不同的方式来动态分配二维数组。您需要提供有关内存中数组的物理结构的更多信息。 【参考方案1】:您需要一个 stride
迭代器。普通指针的++
运算符返回一个偏移量为1
的新指针;对于stride
迭代器,++
运算符将返回一个新的stride
迭代器,其物理偏移量为c
;运营商[]
、+
和--
也是如此;这是一个简单的例子:
template< typename Iterator_Type >
struct stride_iterator
typedef typename std::iterator_traits<Iterator_Type>::value_type value_type;
typedef typename std::iterator_traits<Iterator_Type>::reference reference;
typedef typename std::iterator_traits<Iterator_Type>::difference_type difference_type;
typedef typename std::iterator_traits<Iterator_Type>::pointer pointer;
typedef typename std::iterator_traits<Iterator_Type>::iterator_category iterator_category;
Iterator_Type iterator_;
difference_type step_;
stride_iterator( Iterator_Type it, difference_type dt ) : iterator_(it), step_(dt)
reference operator []( difference_type dt )
return iterator_[dt*step_];
//other ctors, dtor and operators
;
这种情况下,假设持有二维数组的指针是double** dat
,数组的维度是r
by c
,你可以在列索引c1
处创建一个column iterator
与
auto col_itor = stride_iterator<double*> dat + c1, c ;
并使用运算符 [] 访问 dat[r1][c1]
处的元素
auto& elem = col_itor[r1];
【讨论】:
【参考方案2】:不,这是不可能的。您拥有的一种替代方法是创建另一个具有原始数组的 traspose 的二维数组,但这只是无用的,因为每次原始数组更改时您都必须更新此数组。也许还有其他方法可以做到这一点,但列数组却没有。
【讨论】:
博特问题的标题。 OP 没有正确表达他/她想要什么。【参考方案3】:通常第一个维度用于行索引,第二个用于列。
首先,您应该为指针数组(例如int *
)分配内存并将地址保存为指向指针的指针:
int** Volatility = new int * [r];
然后安排循环为每一行分配内存。例如:
for(int i = 0; i < r; i++)
Volatility[i] = new int [c];
但如何使用索引是您的决定。
如果您想使用第一个索引上的列,只需更改逻辑:
int r = 5, c = 10;
int** Volatility = new int * [c];
// allocate memory for each column
for(int i = 0; i < c; i++)
Volatility[i] = new int [r];
如您所见,Volatility[col][row]
是单个元素,Volatility[col]
是指向列的指针。但是现在你不能使用指向行的指针。
【讨论】:
我认为 OP 想要的恰恰相反,即创建指向列的指针,而不是行。嗯……看了题目的题目,或许你是对的 @AntonioGarrido 完全正确 new 不返回 NULL 是错误的情况。它是 bad_alloc。您的代码似乎比 C++ 更像 C【参考方案4】:对我来说,最简单的方法是保留内存块:
double* array2d= new double[r*c];
然后,您可以将指针计算为 array2d+index*r(请记住,内存块逐列存储数组,从第一列到最后一列)。
如果要计算指向行的指针,请使用 array2d+index*r(在这种情况下,内存会逐行存储数组。
如果你想让指针在某个地方使用双运算符 [][],你可以使用:
double **array= new double*[r];
for (int i=1; i<r; ++i)
array[i]= array[i-1]+c;
对于此代码,您可以在代码中使用 array[i][j]。
【讨论】:
以上是关于指向 C++ 中动态分配的二维数组中的一行的指针的主要内容,如果未能解决你的问题,请参考以下文章