通过指针退出函数访问返回

时间:2015-07-11 10:01:55

标签: c++11

我有以下功能

std::tuple<int,val*>Socket::recv(val* values ) // const
{
  char buf [ MAXRECV + 1 ];
  memset ( buf, 0, MAXRECV + 1 );

  int status = ::recv ( m_sock, buf, MAXRECV, 0 );

  if ( status == -1 )
  {
    std::cout << "status == -1   errno == " << errno << "  in Socket::recv\n";
    // return std::make_tuple(0,NULL);//this is not working
  }
  else if ( status == 0 )
  {
    //return std::make_tuple(0,NULL); //this is not working
  }
  else
  {
    struct val* values=(struct val*) buf;
    if(!std::isnan(values->val1) &&
       !std::isnan(values->val2) &&
       !std::isnan(values->val3) &&
       !std::isnan(values->val4),
       !std::isnan(values->val5),
       !std::isnan(values->val6))
       printf("received:%f %f %f %f %f %f\n", values->val1, values->val2,
         values->val3, values->val4, values->val5, values->val6);
      return std::make_tuple(status,values);
  }
}

接收到的值将在函数内正确打印到标准输出中。

但是当我尝试通过调用以下方式从函数中访问这些接收到的值时,我得到的全是0。[创建Socket rcvd对象之后] 你能告诉我如何在函数外部访问这些值吗?

1

std::cout << std::get<1>(rcvd.recv(&values)->val1)
          << std::get<1>(rcvd.recv(&values)->val2)
          << std::get<1>(rcvd.recv(&values)->val3)
          << std::get<1>(rcvd.recv(&values)->val4)
          << std::get<1>(rcvd.recv(&values)->val5)
          << std::get<1>(rcvd.recv(&values)->val6)
          << std::endl;

2

std::cout << std::get<1>(rcvd.recv(&values).val1)
          << std::get<1>(rcvd.recv(&values).val2)
          << std::get<1>(rcvd.recv(&values).val3)
          << std::get<1>(rcvd.recv(&values).val4)
          << std::get<1>(rcvd.recv(&values).val5)
          << std::get<1>(rcvd.recv(&values).val6)
          << std::endl;

3

std::cout << std::get<1>(rcvd.recv(&values)[0])
          << std::get<1>(rcvd.recv(&values)[1])
          << std::get<1>(rcvd.recv(&values)[2])
          << std::get<1>(rcvd.recv(&values)[3])
          << std::get<1>(rcvd.recv(&values)[4])
          << std::get<1>(rcvd.recv(&values)[5])
          << std::endl;

其中“值”来自

struct val {
  val1;
  val2;
  val3;
  val4;
  val5;
  val6;} values;

调用函数或访问struct val的所有三个选项都不适用于我。

你能告诉我吗

  1. 如何从任何功能外部访问这些接收到的值?
  2. 当状态为0或-1
  3. 时,如何将0返回到struct指针[NULL不起作用]

2 个答案:

答案 0 :(得分:0)

尝试

return std::make_tuple<int, val*>(0, nullptr);

元组的类型是从参数中推导出来的,因此使用0,NULL实际上使用的是null常量,其值为0,因此推导的类型为<int,int>

顺便说一句,我认为没有理由在C ++ 11中使用NULL,如果您因某种原因需要它,那么将NULL转换为val*

static_cast<val*>(NULL);

编辑: 其他可行的替代方案是

val* nullval = nullptr;
return std::make_tuple(0, nullval);

或者

return std::make_tuple(0, static_cast<val*>(nullptr));

或(评论建议)

return {0, nullptr};

选择一个看起来更清楚的那个。

答案 1 :(得分:-1)

很幸运,外部功能正在打印零。它可能只是将核心倾倒在你身上:))

你正在做的是在释放堆栈之后访问在堆栈上创建的缓冲区(一旦函数执行完毕)。这是非常不安全的,而且非常非法。

相反,您应该使用malloc(在C中)或运算符new/new[](在C ++中)等函数将数据缓冲区分配到“空闲内存”中。

快速解决方法是更换线

char buf [ MAXRECV + 1 ];

char * buf = new char [ MAXRECV + 1 ];

当你在线上进行类型转换时

struct val* values=(struct val*) buf;

你真的应该确定你所做的是正确的。如果您sizeof()的{​​{1}}超过struct val,则会导致内存访问问题。

使用返回的数据缓冲区后,不要忘记通过调用sizeof(char[MAXRECV + 1])(在C中)或free(在C ++中)来释放它。否则你会遇到所谓的内存泄漏。