我有以下功能
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的所有三个选项都不适用于我。
你能告诉我吗
答案 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 ++中)来释放它。否则你会遇到所谓的内存泄漏。