指向 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++ 中动态分配的二维数组中的一行的指针的主要内容,如果未能解决你的问题,请参考以下文章

指向动态二维字符数组的三重指针的内存分配

C++ new申请二维数组整理

如何在 C++ 中初始化指向动态二维数组的指针 [关闭]

C# 中锯齿状数组的内存分配与 C++ 中的二维数组内存分配

如何在 C++ 中正确使用动态分配的多维数组 [重复]

C++建立动态二维数组