String不是null终止错误

时间:2014-11-12 11:02:41

标签: c++ cstring

我有一个字符串不是空终止错误,虽然我不完全确定原因。在代码的第二部分中使用std :: string是我尝试修复此问题的一种方法,尽管它仍然无法正常工作。

我的初始代码只是使用缓冲区并将所有内容复制到client_id []中。发生的错误。如果错误是正确的,那意味着我得到了client_ id或者theBuffer没有null终止符。我非常确定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);

3 个答案:

答案 0 :(得分:1)

解决问题在于这一行:

sendTalkPackets(next_token1, sizeof(next_token1) + 1, id_clientUse, (unsigned int)std::stoi(theTarget));

sizeof(next_token1)+1将始终给出5(在32位平台上),因为它返回的指针大小不是char数组的大小。

答案 1 :(得分:0)

可能导致此问题(或其他问题)的一件事:As buffersize,您通过sizeof(next_token1) + 1next_token1是 指针,其大小(通常)为4或8 几乎肯定想要strlen(next_token1) + 1。 (或者可能没有 + 1;像这样传递大小的约定通常只包括 '\0'如果是输出缓冲区。还有其他一些 您使用sizeof的地方,可能会遇到类似的问题。

但重做整个逻辑可能会更好 std::string无处不在,而不是所有这些C例程。没有 担心缓冲区大小和'\0'终止符。 (对于协议 缓冲区,我还发现std::vector<char>std::vector<unsigned char> 非常有用。这是在std::string的记忆之前 保证是连续的,但即使在今天,它似乎更符合 与我正在处理的抽象密切相关。)

答案 2 :(得分:0)

你不能只做

std::string theMessage(buffer);
theMessage += "0";

这在两个方面都失败了:

  • std::string构造函数不知道buffer的结束位置,如果buffer不是0终止的话。所以theMessage可能是垃圾并包含随机内容,直到在缓冲区之外的内存中找到一些零字节。
  • 将字符串“0”附加到theMessage无济于事。你想要的是在某处放置零字节,而不是值0x30(这是用于显示零的ascii代码)。

解决此问题的正确方法是在缓冲区的开头之外戳一个字面的零字节buffersize槽。您不能在buffer本身中执行此操作,因为buffer可能不足以容纳额外的零字节。可能性是:

char *newbuffer = malloc(buffersize + 1);
strncpy(newbuffer, buffer, buffersize);
newbuffer[buffersize] = 0; // literal zero value

或者您可以根据自己的喜好构建std::string