如何在 C++ 中获取二维动态数组的行数和列数

Posted

技术标签:

【中文标题】如何在 C++ 中获取二维动态数组的行数和列数【英文标题】:How can I get the number of rows and columns of a 2-D dynamic array in c++ 【发布时间】:2017-07-26 06:17:26 【问题描述】:

我正在尝试制作以动态二维数组为参数的函数(加法、减法、乘积等)。

例如,给定两个二维双精度数组,每个数组有 2 行 2 列:

double** m1;

m1 = new double *[2];

for (int i = 0; i < 2; ++i) 
    m1[i] = new double[2];


double k1 = 1.0;
for (int i = 0; i < 2; ++i) 
    for (int j = 0; j < 2; ++j) 
        m1[i][j] = k1;
        k1 += 2.0;
    


double** m2;

m2 = new double *[2];
for (int i = 0; i < 2; ++i) 
    m2[i] = new double [2];


double k2 = 2.0;
for (int i = 0; i < 2; ++i) 
    for (int j = 0; j < 2; ++j) 
        m2[i][j] = k2;
        k2 += 2.0;
    

我为他们做了一个添加功能。它首先检查两个数组是否具有相同的行数和列数。但是由于数组是完全动态的(行数和列数)并且被声明为指针的指针,所以我无法获得行数和列数。

例如,

的价值
sizeof(m1[0]) 

为4,即双指针的bit大小(大概) 但是,

的价值
sizeof(m1[0][0]) 

是8,是double类型的正确大小。

我想要前者的适当版本。

double** add_m(double **m1_, double** m2_) 
//HERE first part that needs the numbers of arguments' rows and columns.
    if ((sizeof(*m1_) != sizeof(*m2_)) || (sizeof(**m1_) != sizeof(**m2_))) 
        cout << "The sizes of the matrices don't match each other";
        return 0;
    
    else 
//HERE second part that needs the numbers of arguments' rows and columns.
        int num_rows = sizeof(m1_[0])/sizeof(m1[0][0]);//??
        int num_cols = sizeof(m1_[0][0])/sizeof(m1_[0][0]);//??
        double** res;
        res = new double*[num_rows];
        for (int i = 0; i < num_rows; ++i) 
            res[i] = new double[num_cols];
        

        for (int i = 0; i < num_rows; ++i) 
            for (int j = 0; j < num_cols; ++j) 
                res[i][j] = m1_[i][j] + m2_[i][j];
            
        
        return res;
    

编辑: 大多数答案都说使用已经存在的工具,如向量、矩阵。那么只是为了好奇,没办法呢?唯一的方法是从头开始制作类向量类或类矩阵类?

【问题讨论】:

你可以使用std::array和它的size() 我建议使用 class Matrix 来存储行数、列数和值的向量。通过resp可以实现两个dim-access。方法甚至运算符重载。 另外值得一看的是std::vector,因为你从来没有正确地取消分配这些东西,所以这段代码会疯狂地泄漏内存。 三思而后行,你需要存储行数和向量。列数可以通过 vector::size() / nRows 动态确定。 如果将 C 数组作为函数参数传递,它们会“衰减”为指针。因此,sizeof 无法提供函数内部数组的大小。 【参考方案1】:

看来你要做的是处理矩阵。

不幸的是,动态内存分配不存储已分配内存的大小。

这些是一些替代方案:

自己存储矩阵维度

然后您需要将矩阵维度作为参数传递给您的函数。对于您的示例,您可以执行以下操作:

double** add_m(double **m1_, double** m2_, unsigned width, unsigned height)

使用 std::array 或 std::vector

这些类存储元素的数量。

#include <array>
#include <vector>
using namespace std;
// ...
array<array<double, 3>, 3> m1 =  1, 0, 0, 0, 1, 0, 0, 0, 1 ;
unsigned height = m1.size();
unsigned width = m1[0].size();
vector<vector<double> > m2 =  0, 1, 0, 1, 0, 0, 0, 0, 1 ;
height = m2.size();
width = m2[0].size();

制作你自己的矩阵类

它跟踪元素的数量并封装可以用它们完成的操作。

使用定义“矩阵”类的外部库

如果你快速谷歌搜索你会发现一个音调(关键词:线性代数库)。

这些是我测试并喜欢的一些:

Eigen(任意维度,也支持sparse matrices) glm(最多 4x4 矩阵,使用 SIMD 进行更快的计算)

【讨论】:

感谢您的综合回答。【参考方案2】:

C/C++ 中的 Size of() 运算符将为您提供传入的数据类型的大小。因此,在您的示例中,当您说 sizeoff(m1_) 时,您将获得双指针的大小,而不是后面的内存大小它。据我所知,没有干净的方法可以做你想做的事。

@Scheff 在 cmets 中建议的一种更好的方法是为您的矩阵创建一个包装类,并将您的矩阵存储在 std::vector 中(行或列方式)并将此类传递给您的函数以进行算术运算.

这种方法的优点是没有内存泄漏和内存连续性(为了性能)。

如果您不限于使用外部库......像 Eigen 这样的库可以让您轻松。

【讨论】:

以上是关于如何在 C++ 中获取二维动态数组的行数和列数的主要内容,如果未能解决你的问题,请参考以下文章

C++二维数组(指针)做参数

如何在 NativeScript 中创建具有动态行数和列数的表?

如何将控制台窗口的大小调整为设定的行数和列数?

VBA中如何获取一个表格的行数和列数

如何获取ResultSet的行数和列数

如何获取 javascript 中用于 flexbox 和网格布局的行数和列数?