0

我是一个 c++ 新手,只是尝试编写一些代码来自己进行实验。

最近遇到一个无法调试的问题。

char acExpReason[128];
char acReason[] = "An error message is information displayed when an unexpected condition occurs, usually on a computer or other device. On modern operating systems.";

memcpy(acExpReason, acReason, sizeof(acExpReason));
std::string strExpReason(acExpReason);

我使用 VS2005 在每一行添加断点进行调试。

当它到达第二行的断点时,Autos 中的变量名称和值信息为:

  • acReason 0x00f6f78c “ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ” 的char [147]

  • acExpReason 0x00f6f828 “ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̺” 的char [128]

当它到达第三行的断点时,Autos 中的变量名和值信息为:

  • acExpReason 0x00f6f828 “ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̺” 的char [128]

  • acReason 0x00f6f78c “错误消息是发生意外情况时显示的信息,通常在计算机或其他设备上。在现代操作系统上。” 字符 [147]

当它到达第四行的断点时,Autos 中的变量名和值信息为:

  • acExpReason 0x00f6f828 “错误消息是发生意外情况时显示的信息,通常在计算机或其他设备上。在现代 ÌÌÌÌÌÌÌ̺” char [128]

  • acReason 0x00f6f78c “错误消息是发生意外情况时显示的信息,通常在计算机或其他设备上。在现代操作系统上。” 字符 [147]

  • strExpReason Bad Ptr

执行完最后一行后,Autos 中的信息为:

  • acExpReason 0x00f6f828 “错误消息是发生意外情况时显示的信息,通常在计算机或其他设备上。在现代 ÌÌÌÌÌÌÌ̺” char [128]

  • acReason 0x00f6f78c “错误消息是发生意外情况时显示的信息,通常在计算机或其他设备上。在现代操作系统上。” 字符 [147]

  • strExpReason "错误消息是发生意外情况时显示的信息,通常在计算机或其他设备上。在现代 ÌÌÌÌÌÌÌ̺"

基本上我的代码想要做的只是有一个完整的 msg 行存储在 acReason[] 中,并且还有一个固定长度的完整 msg 的副本(这里是 128)。

但我不知道为什么 acExpReason 和 strExpReason(acExpReason 的字符串版本)会以一些我不想要的奇怪字符“ÌÌÌÌÌÌÌ̺”结尾(因为稍后我将使用此字符串与其他字符串进行比较)。

我尝试使用 memcpy、strcpy 和 strncpy,但它们最终都在字符串末尾包含了那组奇怪的字符。

任何人都可以帮忙吗?提前谢谢了。

4

3 回答 3

4
std::string strExpReason(acExpReason);

此构造函数需要 C 风格的字符串。然而acExpReason,它不是 C 风格的字符串,因为它没有终止零字节。(构造函数如何知道字符串中应该有多少字节?)你必须遵守规则。

于 2013-01-15T15:02:05.593 回答
3

在 C 中,所有字符串函数(如 strcpy)和 c++ 的构造函数都std::string作为char*参数,但char*必须以包含 `\0` 的字节终止。

acExpReason 没有以零结尾,因此所有字符串函数都在内存中查找下一个 0 字节。acReason 确实有一个尾随 `\0`。正常的 strcpy 可以工作,因为它也会复制 0 但是因为@VladLazarenko 说缓冲区大小太小,这将导致所有内存被覆盖。

要使 memcpy 工作,您需要复制比缓冲区少一个字节并将缓冲区的最后一个字节设为 0。例如

memcpy(acExpReason, acReason, sizeof(acExpReason)-1);
acReason[sizeof(acExpReason)-1] = 0;
于 2013-01-15T15:02:14.103 回答
2

您还可以使用string接受迭代器范围的构造函数 -

std::string strExpReason(acExpReason, acExpReason+sizeof(acExpReason));
于 2013-01-15T15:08:37.943 回答