【问题标题】:How do I pass a truly immutable 2D array to a function?如何将真正不可变的二维数组传递给函数?
【发布时间】:2016-12-27 20:18:11
【问题描述】:

我有这个功能:

void foo(const double *const *matrix, unsigned num_rows, unsigned num_columns){
    //matrix[0][0] = 5; // ERROR: expression must be a modifiable lvalue
    for (unsigned i = 0; i < num_rows; i++) delete matrix[i];
    delete matrix;
}

...其中函数无法更改矩阵中任何给定索引处的值,但它仍然能够删除矩阵或其任何行。有没有办法传入一个二维矩阵并保证它不会以任何方式改变?

编辑:看起来没有办法做到这一点,所以我可能会改用向量。

【问题讨论】:

  • 我会开始转储原始数组,但使用 std::array&lt;std::array&lt;double,num_rows&gt;,num_cols&gt;std::vector&lt;std::vector&lt;double&gt;&gt;
  • 请参阅“1D or 2D array, what's faster?”,了解为什么您很可能不希望拥有二维动态数组数组或vector&lt;vector&lt;T&gt;&gt; 用于(密集)矩阵。我的答案有一个小的矩阵示例类。 (您当然可以只拥有vector&lt;T&gt; 并自己处理映射。)
  • 酷提示,Pixelchemist。但是如果我知道我的矩阵的大小并且知道它永远不会改变,我认为对于作为开发人员和用户的我自己来说,向量向量将更容易可视化。该程序将(静态)图像作为输入并输出一些关于它的数据。我宁愿让用户构建一个二维向量,也不愿让他们学习一维方法。你同意吗?
  • @user3076399:我宁愿有一个带有Matrix m(20,20);m[0][0] = 1.0;m(0, 0) = 1.0; 之类的类,因为安全地使用向量向量需要对每个子向量等进行大小/边界检查.
  • @Pixelchemist 每个子向量的长度总是相同的,因为矩阵是正方形的。

标签: c++ arrays constants


【解决方案1】:

没有。

delete 可以在指针上调用,即使它作为 const &amp; 传递,甚至声明为 const,因为指针不会被更改。

也没有办法阻止某人这样做

unsigned char *p = (unsigned char *)your_precious_data_pointer;
*p = 42;

克服它。

常量正确性旨在检测意外错误,而不是防止程序员的故意行为。这与安全无关。

它是否是防止意外错误的好工具甚至可以争论。

【讨论】:

    【解决方案2】:

    没有。但是无论如何你都不应该使用newdelete 和原始拥有指针,当然也不应该使用delete 任意指针。

    如果这还不足以切换到智能指针和容器...您实际上是通过deleteing 触发了未定义的行为,而这些东西显然已被new[] 分配。这是使用原始拥有指针要注意的另一个错误。

    顺便说一句,这不是一个二维数组,而是一个指针数组。

    【讨论】:

    • 为什么不呢?我应该改用什么?
    • @juanchopanza 它是。我给自己留了余地,不要输入“指向指向doubles 的更多数组的第一个元素的指针数组的第一个元素的指针”。
    • @Quentin 是的,但我们甚至不知道它是指向数组第一个元素的指针。就函数而言,参数是一个指针。
    • @juanchopanza 信任调用者,因此for-loop 不会直接从数组的末端射入 UB 区域。毕竟,原始指针都是关于信任的。
    • @user3076399 你应该看看std::vectorstd::unique_ptr
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2020-11-01
    相关资源
    最近更新 更多