繁体   English   中英

复制构造函数更改std :: string

[英]Copy constructor alters std::string

有人可以告诉我这里发生了什么吗? (我对C ++不够熟悉)。

我有一个std::string ,它以4 int32_t开头,方法是使用二进制stringstream并调用方法write()

当我这样做时, indextypetag (4个int32-ts中的3个)是正确的。

SocketInfo currentSocketInfo;
currentSocketInfo.header.reserve(_headerLength);
int iResult = recv(socket, &currentSocketInfo.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 ,但是我认为它的行为类似于memcpycurrentSocketInfo.header一些char

根据你的描述, indextypetag010 ,分别,这样我可以假设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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM