У меня есть строка, это не ошибка с завершением нулевой ошибки, хотя я не совсем понимаю, почему. Использование std :: string во второй части кода - одна из моих попыток исправить эту проблему, хотя она все еще не работает.
Мои начальные коды просто использовали буфер и копировали все в client_id []. Ошибка, чем произошла. Если ошибка правильная, это означает, что у меня есть либо идентификатор client_, либо у theBuffer нет нулевого терминатора. Я уверен, что client_id в порядке, поскольку я вижу это в режиме отладки. Странная вещь - буфер также имеет нулевой ограничитель. Не знаю, что не так.
char * next_token1 = NULL;
char * theWholeMessage = &(inStream[3]);
theTarget = strtok_s(theWholeMessage, " ",&next_token1);
sendTalkPackets(next_token1, sizeof(next_token1) + 1, id_clientUse, (unsigned int)std::stoi(theTarget));
Внутри sendTalkPackets есть. Я получаю строку, которая не имеет нулевого конца в последней строке.
void ServerGame::sendTalkPackets(char * buffer, unsigned int buffersize, unsigned int theSender, unsigned int theReceiver)
{
std::string theMessage(buffer);
theMessage += "0";
const unsigned int packet_size = sizeof(Packet);
char packet_data[packet_size];
Packet packet;
packet.packet_type = TALK;
char client_id[MAX_MESSAGE_SIZE];
char theBuffer[MAX_MESSAGE_SIZE];
strcpy_s(theBuffer, theMessage.c_str());
//Quick hot fix for error "string not null terminated"
const char * test = theMessage.c_str();
sprintf_s(client_id, "User %s whispered: ", Usernames.find(theSender)->second.c_str());
printf("This is it %s ", buffer);
strcat_s(client_id, buffersize , theBuffer);
Понимает, что проблема заключается в этой строке:
sendTalkPackets(next_token1, sizeof(next_token1) + 1, id_clientUse, (unsigned int)std::stoi(theTarget));
sizeof (next_token1) +1 всегда будет давать 5 (на 32-битной платформе), потому что возвращает размер указателя, а не размер массива char.
Одна вещь, которая может вызвать это (или другие проблемы): В качестве buffersize
вы передаете sizeof(next_token1) + 1
. next_token1
- указатель, который будет иметь постоянный размер (обычно) 4 или 8. Вы почти наверняка хотите strlen(next_token1) + 1
. (Или, может быть, без + 1
; соглашения для передачи таких размеров обычно включают только '\0'
если это выходной буфер. Есть несколько других мест, где вы используете sizeof
, что может иметь схожие проблемы.
Но, вероятно, было бы лучше переделать всю логику на использование std::string
всюду, а не на все эти подпрограммы C. Не беспокойтесь о размерах буфера и терминаторах '\0'
. (Для буферов протоколов я также нашел, что std::vector<char>
или std::vector<unsigned char>
весьма полезен. Это было до того, как память в std::string
была гарантирована непрерывной, но даже сегодня она похоже, более тесно соответствует абстракции, с которой я имею дело.)
Вы не можете просто сделать
std::string theMessage(buffer);
theMessage += "0";
Это не удается на двух фронтах:
std::string
не знает, где заканчивается buffer
, если buffer
не оканчивается на 0. Таким образом, theMessage
потенциально будет мусором и включает случайные вещи, пока в памяти не будет найден нулевой байт за пределами буфера.theMessage
не помогает. Вы хотите поместить нулевой байт где-нибудь, а не значение 0x30 (это код ascii для отображения нуля). Правильный способ приблизиться к этому, состоит в том, чтобы buffersize
буквально нулевые байтовые интервалы buffersize
за пределы начала буфера. Вы не можете сделать это в самом buffer
, потому что buffer
может быть недостаточно большим, чтобы разместить этот дополнительный нулевой байт. Возможность:
char *newbuffer = malloc(buffersize + 1);
strncpy(newbuffer, buffer, buffersize);
newbuffer[buffersize] = 0; // literal zero value
Или вы можете построить std::string
, в зависимости от того, что вы предпочитаете.
theMessage += "0";
Вы ожидали, что это добавляет нулевой терминатор? Если так, это не так.std::string
, и только когда функция вызываетconst char*
, вы в конечном итоге используетеc_str()
членc_str()
для получения строки в стиле C.