1

当我运行示例代码时,wordLength 为 7(因此输出为 7)。但是我的 char 数组最后得到了一些非常奇怪的字符。

wordLength = word.length();

cout << wordLength;

char * wordchar = new char[wordLength]; //new char[7]; ??

for (int i = 0; i < word.length(); i++) //0-6 = 7
{
    wordchar[i] = 'a';
}

cout << wordchar;

输出:7 aaaaaaa²²²²¦¦¦¦¦ÂD╩2¦♀

期望的输出是:aaaaaa... 它背后的垃圾是什么?它是如何结束的?

4

4 回答 4

5

您应该\0在末尾添加wordchar.

char * wordchar = new char[wordLength +1];
//add chars as you have done
wordchar[wordLength] = `\0`

原因是 C 字符串是空终止的。

于 2013-09-29T16:21:29.860 回答
3

C 字符串以 '\0' 字符结尾,表示它们的结束(相反,C++std::string只是单独存储长度)。

在将字符复制给wordchar您时并没有终止字符串,因此,当operator<<输出时wordchar,它会继续运行,直到找到\0恰好位于 指向的内存位置之后的第一个字符wordchar,并在此过程中打印所有垃圾值恰巧在记忆中。

要解决此问题,您应该:

  1. 使分配的字符串长 1 个字符;
  2. \0在末尾添加字符。

不过,在 C++ 中,您通常只想使用std::string.

于 2013-09-29T16:24:00.753 回答
1

利用: -

char * wordchar = new char[wordLength+1]; // 1 extra for null character

在 for 循环之前和

wordchar[i] ='\0'

在 for 循环之后,C 字符串以空值结尾。

没有它,它会继续打印,直到找到第一个空字符,打印所有垃圾值。

于 2013-09-29T16:21:18.427 回答
1

您避免尾随零,这就是原因。

在 C 和 C++ 中,整个生态系统处理字符串长度的方式是它假定尾随零('\0'或简单的0数字)。这与例如帕斯卡字符串不同,其中内存表示以数字开头,该数字告诉有多少下一个字符构成特定字符串。

因此,如果您要存储某个字符串内容,则必须为尾随零分配一个额外的字节。如果您操纵内存内容,您将始终牢记尾随零并保留它。否则strstr,其他字符串操作函数可能会在偏离轨道时改变内存内容并继续处理以下内存部分。没有尾随零strlen也会给出错误的结果,它也会计数,直到它遇到第一个零。

您不是唯一犯此错误的人,它通常在安全漏洞及其漏洞利用中扮演重要角色。该漏洞利用了函数偏离轨道并操纵其他东西的副作用,而不是最初的意图。这是 C 语言中非常重要和危险的部分。

在 C++ 中(如您标记您的问题),您最好使用 STLstd::string和 STL 方法而不是 C 样式操作。

于 2013-09-29T16:21:33.730 回答