在第三方函数中使用向量引用时出现意外错误

Posted

技术标签:

【中文标题】在第三方函数中使用向量引用时出现意外错误【英文标题】: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 指向其他地方。您没有发布完整的程序,但我假设您有其他一些分配内存的函数,然后将该内存的地址传递给该函数,期望将值写入其中。您的第一个案例确实将值写入其中,您的第二个案例没有。 【参考方案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)。而且他们必须传递一个指针变量,而不是一个隐式衰减为指针的数组。

【讨论】:

我理解我的错误,虽然无法理解您提供的替代选项。而且我也无法更改调用者函数。谢谢

以上是关于在第三方函数中使用向量引用时出现意外错误的主要内容,如果未能解决你的问题,请参考以下文章

在 url 模式中使用 include() 时出现意外的 NoReverseMatch 错误

在 C++ 中使用向量时出现分段错误

当我尝试将函数的参数设置为默认值时出现意外错误

错误:使用 Fetch API 向第三方 API 发出 GET 请求时出现“TypeError:无法获取”

从第三方 HTML 控件使用 Google SMTP 发送邮件时出现问题

意外令牌:使用休眠、JPQL 和 postgres 函数时出现“<function_name>”错误