2015-02-05 3 views
0

Может кто-нибудь, пожалуйста, объясните мне, что здесь происходит? (Я недостаточно знаком с C++).Копировать конструктор изменяет std :: string

У меня есть std::string, который начинается с 4 int32_t, добавленного с помощью двоичного stringstream и вызывающего метод write().

Когда я это делаю, index, type и tag (3 из 4 int32-ts) верны.

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; 
}; 
+0

Что такое 'SocketInfo'? Не могли бы вы дать нам [минимальный полный пример] (http://stackoverflow.com/help/mcve)? – Beta

+0

Добавил класс SocketInfo, извините, что забыл. –

+0

", когда я передаю currentSocketInfo функции по значению, затем выполните то же самое reinterpret_cat и присваивания:« Покажите этот код. Кроме того, какой компилятор вы используете и какую версию? –

ответ

0

Вы не показали, что внутри recv, но я предполагаю, что он сделал что-то аналогично memcpychar s по currentSocketInfo.header.

По вашему описанию, index, type и tag являются 0, 1 и 0, соответственно, так что я могу предположить, что currentSocketInfo.header содержит {0,0,0,0, 1,0,0,0, 0,0,0,0} после выполнения recv.

Следующая вещь, string «s копировать конструкт копировать только„строка“, которая является 0 -ended char*, так что не только копировать вещи, пока 0 столкнулись.

Теперь, с currentSocketInfo.header быть {0,0,0,0, 1,0,0,0, 0,0,0,0}, в SocketListener::appendCurrentMessageFromSocket скопированный SocketInfo socketInfo есть что-то вроде {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

Смежные вопросы