【问题标题】:How can I get the number of rows and columns of a 2-D dynamic array in c++如何在 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 无法提供函数内部数组的大小。

标签: c++ arrays dynamic 2d


【解决方案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();

制作你自己的矩阵类

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

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

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

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

【讨论】:

  • 感谢您的综合回答。
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2013-05-14
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 2021-12-30
    • 2011-01-11
    • 1970-01-01
    相关资源
    最近更新 更多