【问题标题】:Unexpected error when using a reference of vector in a third pary function在第三方函数中使用向量引用时出现意外错误
【发布时间】:2017-07-06 02:53:04
【问题描述】:

我应该在下面的第三方函数中为x 输入一个值数组。

bool MyNLP::get_starting_point(Index n, bool init_x, double* x,
                           bool init_z, double* z_L, double* z_U,
                           Index m, bool init_lambda,
                           double* lambda)
{
      //example
      x[0] =0.5;
      x[1] =1.5;

      //similarly other values also initialized.

      return true;
}

我得到了正确的结果。

下一个案例

现在我没有直接输入x 的值,而是使用了nlp 类成员的值向量。

class nlp
{
std::vector<double> m_val;

public:
std::vector<double>& get_val()
{
     m_val.push_back(0.5);
     m_val.push_back(1.5);
     return m_val;
}
}

我在盗贼函数内部调用了函数get_val

bool MyNLP::get_starting_point(Index n, bool init_x, double* x,
                           bool init_z, double* z_L, double* z_U,
                           Index m, bool init_lambda,
                           double* lambda)
{
      //example
      //x = &(m_nlp->get_val()).at(0);
      std::vector<double>& values = m_nlp->get_val();
      x = &values.at(0);
      assert(x[0] == 0.5);
      assert(x[1] == 1.5);

      //similarly other values also initialized.

      return true;
}

我在第一种情况下使用与以前相同的值初始化x,但输出不同。我的断言也没有失败。我不知道这里发生了什么。

两种不同输出的原因可能是什么?

【问题讨论】:

  • == 不适合比较浮点值。做一个epsilon测试会更好。如果您仍有问题,请发帖MCVE
  • @M.M 虽然这通常是正确的,但 0.51.5 具有精确的表示,所以这种情况应该不会失败。
  • 在第二个示例中,您没有将任何值写入原始x 指向的位置(您只需将本地x 指向其他地方),也许您打算double *p = &amp;m_nlp-&gt;get_val().at(0); x[0] = p[0]; x[1] = p[1]; 或其他东西
  • @M.M 我将x 指向向量的第一个元素的地址,并通过断言确保数组x 包含我想要的确切元素
  • 是的。你的两个案例做不同的事情。第一个将值写入x 指向的位置。第二个使x 指向其他地方。您没有发布完整的程序,但我假设您有其他一些分配内存的函数,然后将该内存的地址传递给该函数,期望将值写入其中。您的第一个案例确实将值写入其中,您的第二个案例没有。

标签: c++ function vector reference


【解决方案1】:

在您的第一个版本中,您通过x 间接修改调用方数组的元素。

在第二个程序中,您将重新分配局部指针变量x 以指向向量中的数据。这对调用者的数组没有影响,因为x 是按值传递的,而不是按引用传递的。

您需要将值从向量复制到数组。

bool MyNLP::get_starting_point(Index n, bool init_x, double* x,
                           bool init_z, double* z_L, double* z_U,
                           Index m, bool init_lambda,
                           double* lambda)
{
      //example
      //x = &(m_nlp->get_val()).at(0);
      std::vector<double>& values = m_nlp->get_val();
      for (int i = 0; i < values.size(); i++) {
        x[i] = values[i];
      }

      return true;
}

另一种选择是更改代码,以便 x 通过引用传递:double *&amp;x。但这需要对调用者进行更改:他们不应该为他们传递的指针分配内存,因为它不会被释放(除非你在这个函数中添加delete[] x)。而且他们必须传递一个指针变量,而不是一个隐式衰减为指针的数组。

【讨论】:

  • 我理解我的错误,虽然无法理解您提供的替代选项。而且我也无法更改调用者函数。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-16
  • 1970-01-01
  • 2022-06-20
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多