溢出的char数组每次都会覆盖完全相同的字符串 - 为什么?

时间:2014-05-20 10:00:15

标签: c++ arrays string char

我有以下代码,显示使用char数组对字符串的危险:

int main(){
    char password[] = "SECRET";
    char msg[10], ch;
    int i = 0;

    cout << "Please enter your name:";
    while((ch = getchar()) != '\n'){
            msg[i++] = ch;
    }
    msg[i] = '\0';

    cout << "\n\nHello " << msg << endl;
    cout << "The password is " << password;
}

当我输入超过16个字符的名称(存储在char msg[10])时,这16个字符后面的所有内容都会替换char password[]中存储的值(“SECRET”) )。

  1. 为什么会这样? (一般的好奇心
  2. 为什么16个字符而不是10个 - 数组的大小?
  3. 为什么总是password被覆盖而不是其他变量或内存的其他部分我不会立即注意到?
  4. 然后使用char []对字符串有什么好处?
  5. 编辑:更新后续问题:
      5. 为了回应passwordmsg彼此相邻声明的论点,我按照以下方式对声明块进行了改组:

    char password[] = "SECRET";
    char ch;
    int i = 0;
    char msg[10];
    

    但是,没有变化   6。为了回应可能导致msgpassword之间的差距为6(字节?)长的可能性,我已多次重新编译代码,包括上面的改组。仍然没有变化。

    对于为什么有任何建议?

4 个答案:

答案 0 :(得分:4)

前三个问题的答案是相同的:因为那是你的编译器如何选择在堆栈上布置这些变量。标准中没有任何内容可以保证 - 实际上,您所做的是未定义的行为 - 任何事情都可能发生。

更改编译器,甚至编译器设置,以及其他可能发生的事情。或不。没有说明。

至于4,除了与C代码的互操作性,或其他需要C风格字符串的API,基本上没有。

答案 1 :(得分:2)

您的两个数组msgpassword是静态的,因此已被放置在堆栈中,这意味着它们彼此靠近。

具体细节取决于实现,可能会在编译器和优化级别之间发生变化。在分配内存时,编译器可能会对堆栈进行一些填充,msg[0]password[0]之间存在16个字节的差距。

password每次都会被覆盖,因为它恰好位于您的堆栈上msg之上。如果您使用了不同的编译器,或者在代码中交换了它们的位置,则可能不是。如何在堆栈上分配内容不会在执行之间发生变化;它是在编译时确定的(它是静态的),而不是运行时。

请注意,原则上,编译器可以随意执行任何操作!我们只能根据典型的编译器行为做出有根据的猜测。 如果你真的想知道发生了什么,你必须看看输出组件。

std::string(对于C ++)通常比char[]更可取 - 它更安全,因为它实现了绑定检查并管理自己的内存。

答案 2 :(得分:2)

1。在您的情况下,内存存储如下:

 msg                |   |i      |password
| | | | | | | | | | |1|2|3|4|5|6|S|E|C|R|E|T|\0

然后你逐步写下msg:

 msg                |           |password
|A|Z|E|R|T|Y|U|I|O|P|1|2|3|4|5|6|S|E|C|R|E|T|\0

但如果你继续:

 msg                |           |password
|A|Z|E|R|T|Y|U|I|O|P|1|2|3|4|5|6|Q|W|E|R|T|Y|

因为char数组不检查长度。 (搜索溢出)。

2.你在记忆中写道,你会删除两者之间的一切,也许是我或者不属于你的程序的东西。

3.在覆盖密码之前需要6个字符。它可能是0char和数百万。

4.除非您存储已定义的字节数组......否则,这就是代码证明的要点。

更新:

  1. 更改代码的位置不会改变填充,添加变量,数组或更好:使用不同的编译器,这样即使在优化之后,二进制也会发生变化。

  2. 重新编译不会改变生成的二进制文件,因为编译器会做同样的事情。

答案 3 :(得分:1)

1)在数组外写字会访问其他内容 2)可能对齐。
3)机会。任何事情都可能发生 4)什么都没有!