【问题标题】:Does it need to initialise the variable after allocating memory?分配内存后是否需要初始化变量?
【发布时间】:2021-09-19 20:21:36
【问题描述】:

我正在尝试在 C++ 中实现矩阵乘法。我找到了一个示例代码,它使用了一个写入.h.cpp 文件的类。这只是与我的问题相关的代码的一部分:

#include "Matrix.h"

// Constructor - using an initialisation list here
Matrix::Matrix(int rows, int cols, bool preallocate): rows(rows), cols(cols), size_of_values(rows * cols), preallocated(preallocate)
{
   // If we want to handle memory ourselves
   if (this->preallocated)
   {
      // Must remember to delete this in the destructor
      this->values = new double[size_of_values];
   }
}

void Matrix::matMatMult(Matrix& mat_left, Matrix& output)
{
   // The output hasn't been preallocated, so we are going to do that

      output.values = new double[this->rows * mat_left.cols];

   // Set values to zero before hand
   for (int i = 0; i < output.size_of_values; i++)
   {
      output.values[i] = 0;
   }

我想知道为什么他们使用 0s output.values[i] = 0; 的输出矩阵来初始化它之前已经分配了内存?

【问题讨论】:

  • 初始化可以更简单:output.values = new double[this-&gt;rows * mat_left.cols]{};
  • "虽然之前已经分配了内存?" - 每次调用 matMatMult 时都会进行新的分配。
  • 这取决于算法应该做什么。如果你用 1:s 填充它,这个算法会做正确的事吗?
  • 如果你不初始化它然后继续读取你的程序格式错误的任何索引处的值。它的行为是不确定的。
  • 你不能通过实验可靠地检查未定义的行为,因为它可能看起来有效,它是未定义的

标签: c++ memory matrix-multiplication


【解决方案1】:

cppreferencenew 表达式:

new-expression 创建的对象按照以下规则进行初始化:

  • [...]
  • 如果 type 是数组类型,则初始化对象数组。
    • 如果没有初始化,每个元素都是默认初始化的
    • 如果初始化程序是一对空括号,则每个元素都进行值初始化。

“default-initialized”ints 通俗地说是没有初始化的。它们具有不确定的值。空的一对括号指的是 Ted 在评论中提到的内容:

output.values = new double[this->rows * mat_left.cols]{};

值初始化在here 中描述。这里适用的情况是

  • 否则,对象被零初始化。

我想知道为什么他们使用 0 的输出矩阵进行初始化 output.values[i] = 0;虽然之前已经分配了内存?

分配内存和初始化对象是两个独立的步骤。是的,元素必须初始化,分配内存是不够的。

【讨论】:

  • 因此,通过在我们分配数组后初始化数组,我们实际上是在确保我们的数组包含我们想要的值,而不是某个随机数。
  • @RahaMoosavi 不,没有随机数。它与非数组类似。考虑int x; std::cout &lt;&lt; x;x 未初始化,因此代码具有未定义的行为。你可能会在屏幕上打印一些数字,可能是0,但程序也可能什么也不打印,它可能会擦除你的硬盘,它可能会让鼻恶魔飞出你的鼻子等等。没有规则指定程序将做什么,因为代码具有未定义的行为
  • 这里是一些关于未定义行为的信息:https://en.cppreference.com/w/cpp/language/ub
  • 非常感谢您的澄清,另一个快速的问题,当我们声明一个双精度数组时,我们不保证这个指针指向的值是双精度类型的吗?
  • @RahaMoosavi new 确实分配内存并创建对象,它们是doubles
猜你喜欢
  • 2017-11-10
  • 2010-10-12
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 2019-07-26
  • 1970-01-01
相关资源
最近更新 更多