【问题标题】:What happens with the dynamic memory allocation, of a matrix with different size of columns on each line?对于每行具有不同列大小的矩阵的动态内存分配会发生什么?
【发布时间】:2020-10-25 14:47:30
【问题描述】:

我正在尝试在 C++ 中创建一个矩阵,其形状像这样:

n = 行数; 例如,如果我输入 n = 4,我的矩阵应该如下所示: 1 23 456 78910

我已经成功完成了以下代码:

int n;
cout << "Introduceti n: ";
cin >> n;
int** a = new int*[n];
for (int i = 0; i < n; i++) {
    a[i] = new int[i+1];
}

for (int i = 0; i < n; i++) {
    for (int j = 0; j < i+1; j++) {
        *(*(a + i) + j) = (i * i + i) / 2 + j +1;
    }
}


for (int i = 0; i < n; i++) {
    for (int j = 0; j < i+1; j++) {
        cout << *(*(a + i) + j) << "|";
    }
    cout << endl;
}

问题是:如果我指示指针停止在 a[0][0] 处初始化,为什么我可以访问 a[0][1] 并显示一个值?

【问题讨论】:

  • 首先,对于任何指针或数组a 和索引i,表达式*(a + i)恰好等于a[i]。后者更容易阅读、书写和理解。特别是如果你有一个像你这样的锯齿状数组。
  • 为什么我可以访问 a[0][1] -- C++ 不会阻止你做这样的坏事。 C++ 是一门强大的语言,但能力越大,责任越大。
  • C++ 中没有什么可以阻止您访问不应该访问的内存。如果你这样做,只是你的程序有undefined behaviour
  • 并且未初始化的内存是未初始化的。它将具有不确定的 内容和值,并且将这些值用于任何事物 会导致未定义的行为。 C++ 也没有任何边界检查,不超出边界是你的责任。
  • 您在这里找到什么有用的东西了吗?为了 SO 社区的利益,您发布反馈是件好事。

标签: c++ arrays matrix memory dynamic


【解决方案1】:

您可以访问内存,无论它是被初始化还是分配。 您可以自行编写代码来避免那些可能不需要的事件,或者有适当的机制来检测它们。

所以,

为什么我可以访问 [0][1]...
如上所述

...它向我展示了一个价值,...
因为内存中的每一点都有一些价值。

试试下面的代码,你可能会明白你在做什么。

您可以占用的最少内存是确保您具有连续分配。因此,您宁愿在线性数组中为 (n*(n+1)/2) 个整数(三角矩阵的大小)分配存储空间,然后简单地定义用于访问元素 (i,j) 的函数/宏。可能需要不超过 20 行代码...如果您想确保工作安全,您可以包含一些检查以增加几行代码。

#include <iostream>

using namespace std;

int main() {
    int n;
    cout << "Introduceti n: ";
    cin >> n;
    int **a = new int*[n];
    for (int i = 0; i < n; i++) {
        a[i] = new int[i + 1];
    }

    cout << "Size of int is " << sizeof(int) << endl;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i + 1; j++) {
            *(*(a + i) + j) = (i * i + i) / 2 + j + 1;
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i + 1; j++) {
            cout << *(*(a + i) + j) << "|";
        }
        cout << endl;
    }

    cout << "a[0][0] @" << &(a[0][0]) << "=" << a[0][0] << endl;
    cout << "a[0][1] @" << &(a[0][1]) << "=" << a[0][1] << endl;

    return 1;
}

【讨论】:

  • 我现在从这里所有的 cmets 中得到它。还有一个问题:我的代码是否比使用 a[4][4] 初始化 2D 数组但每行仅显示 i+1 列更节省内存?
  • @AlexIvan - 内存分配在许多方面取决于实现。但可以肯定的是,你能做的最好的事情就是确保你有连续的分配。因此,您宁愿为 (n*(n+1)/2) 个整数(三角矩阵的大小)分配存储空间,然后简单地定义用于访问元素 (i,j) 的函数/宏。可能需要不超过 20 行代码...如果您想安全地工作,您可以包含一些检查以增加几行。
猜你喜欢
  • 1970-01-01
  • 2017-11-02
  • 1970-01-01
  • 2021-12-19
  • 2015-11-04
  • 1970-01-01
  • 2011-04-11
  • 2013-08-30
相关资源
最近更新 更多