[英]Copy constructor alters std::string
有人可以告诉我这里发生了什么吗? (我对C ++不够熟悉)。
我有一个std::string
,它以4 int32_t
开头,方法是使用二进制stringstream并调用方法write()
。
当我这样做时, index
, type
和tag
(4个int32-ts中的3个)是正确的。
SocketInfo currentSocketInfo;
currentSocketInfo.header.reserve(_headerLength);
int iResult = recv(socket, ¤tSocketInfo.header[0], _headerLength, 0);
auto headerIntPtr = reinterpret_cast<const int32_t*>(currentSocketInfo.header.c_str());
int32_t index = headerIntPtr[1];
int32_t type = headerIntPtr[2];
int32_t tag = headerIntPtr[3];
appendCurrentMessageFromSocket(socket, currentSocketInfo);
但是,当我按值将currentSocketInfo
传递给函数时,然后执行完全相同的reinterpret_cat和赋值,则值是不同的。 (首先,它们就像0、1、0,但是在函数调用之后,它们像这样-252142 <-不是精确数字,只是相似)。
void SocketListener::appendCurrentMessageFromSocket(SOCKET socket, SocketInfo socketInfo) {
auto headerIntPtr = reinterpret_cast<const int32_t*>(socketInfo->header.c_str());
int32_t index = headerIntPtr[1];
int32_t type = headerIntPtr[2];
int32_t tag = headerIntPtr[3];
}
这是SocketInfo
类,与问题相关的部分只是标题字段:
class SocketInfo {
public:
bool waitingForWholeMessage;
std::string header;
std::string body;
int32_t expectedLength;
};
您没有显示recv
,但是我认为它的行为类似于memcpy
到currentSocketInfo.header
一些char
。
根据你的描述, index
, type
和tag
是0
, 1
和0
,分别,这样我可以假设currentSocketInfo.header
包含{0,0,0,0, 1,0,0,0, 0,0,0,0}
执行recv
。
接下来的事情是, string
的copy构造仅复制“ string”,即以0
结尾的char*
,因此它仅复制内容直到遇到0
。
现在,将currentSocketInfo.header
设置为{0,0,0,0, 1,0,0,0, 0,0,0,0}
,在SocketListener::appendCurrentMessageFromSocket
复制的SocketInfo socketInfo
SocketListener::appendCurrentMessageFromSocket
具有类似{0}
,这是一个空字符串。
因此,当您执行auto headerIntPtr = reinterpret_cast<const int32_t*>(socketInfo->header.c_str());
, headerIntPtr
指向无意义的内存地址。
以下代码应产生与您所经历的相同的效果:
(为简单起见,PS仅将您的索引更改为0、1和2)
char c[12] = {0,0,0,0, 1,0,0,0, 0,0,0,0};
std::string s1;
s1.resize(12);
// should be the same effect like `recv`
char* tos1 = const_cast<char*>(s1.c_str());
memcpy(tos1, c, 12);
// end of `recv`
auto p = reinterpret_cast<const int*>(s1.c_str());
int i1 = p[0]; // 0
int i2 = p[1]; // 1
int i3 = p[2]; // 0
std::string s2 = s1;
p = reinterpret_cast<const int*>(s2.c_str());
i1 = p[0]; // 0xcccccc00
i2 = p[1]; // 0xcccccccc
i3 = p[2]; // 0xcccccccc
我使用VS2012 Ultimate测试了以上代码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.