与字符串相关

时间:2012-04-24 11:20:13

标签: c++ c

//SECTION I:
void main()
{
    char str[5] = "12345";  //---a)
    char str[5] = "1234";   //---b)
    cout<<"String is: "<<str<<endl;
}
Output: a) Error: Array bounds Overflow.
        b) 1234

//SECTION II:
void main()
{
    char str[5];
    cout<<"Enter String: ";
    cin>>str;
    cout<<"String is: "<<str<<endl;
}
  

我尝试了许多不同的输入字符串,令我惊讶的是,我得到了奇怪的结果:

     
    

案例I:输入字符串:1234,输出:1234(没问题,因为这是预期的行为)

         

案例II:输入字符串:12345,输出:12345(编译器报告没有错误但是我期待错误:数组边界溢出。)

         

案例III:输入字符串:123456,输出:123456(编译器报告没有错误但是我期待错误:数组边界溢出。)

         

............................................... ..

         

............................................... ..

         

案例VI:输入字符串:123456789,输出:123456789(错误:unhandeled exception.Access Violation。)

  

我的疑问是,当我在第一部分中分配的字符多于其容量时,编译器报告了ERROR:数组边界溢出。

但是,当我在第二部分尝试同样的事情时,我并没有发现任何错误。为什么会这样?请注意:我在Visual Studio上执行了此操作

6 个答案:

答案 0 :(得分:4)

char str[5] = "12345";

这是一个编译时错误。您将长度为6的字符串(请注意附加的null-termination)分配给大小为5的数组。


char str[5];
cin>>str; 

这可能会产生运行时错误。根据您输入的字符串的长度,您提供的缓冲区(大小为5)可能太小(再次注意空终止)。


编译器当然无法在运行时检查用户输入。如果幸运的话,分段错误会通知您这样的访问冲突。确实,任何事情都可能发生。

违反访问权限的抛出异常不是强制性的。要解决这个问题,你可以自己实现数组边界检查,或者(可能更好)有容器类根据需要调整它们的大小(std::string):

std::string str;
cin >> str;

答案 1 :(得分:4)

您所看到的是未定义的行为。你正在编写数组越界,在这种情况下可能发生任何事情((包括看到你期望的输出)。

答案 2 :(得分:3)

  

我尝试了许多不同的输入字符串,令我惊讶的是,我得到了   奇怪的结果:

这种现象称为未定义行为(UB)。

只要您输入的字符数超过char阵列所能容纳的字符数,您就会邀请UB 有时,它可能会工作,它可能无法工作,它可能会崩溃。简而言之,没有明确的模式。

[旁注:如果编译器允许编译void main(),那么它不符合标准。]

答案 3 :(得分:2)

这是因为在第二种情况下,编译器无法知道。只有在运行时,才会出现错误。默认情况下,C / C ++不提供运行时边界检查,因此无法识别错误,但会“中断”程序。但是,这种中断不必立即显示,但是当str指向内存中仅保留固定字节数的位置时,您只需编写更多字节。

您的计划的行为将是未定义的。通常,在您的特定情况下,它可能会继续工作,您将覆盖其他组件的一些记忆。一旦你写了很多东西来访问禁止的内存(或两次释放相同的内存),你的程序就会崩溃。

答案 4 :(得分:2)

char str[5] = "12345" - 在这种情况下,您没有为空终结符留出空间。因此,当应用程序尝试打印str时,只要没有遇到null,它就会一直打开,最终踩到伪造的内存并崩溃。

`cin情况下,cin操作在字符串末尾填充0,因此这会阻止程序在内存中走得太远。

然而,根据我的经验,当内存超支违反规则时,事情会变得疯狂,并且寻找一个原因,在一个案例中它起作用,而在另一个案例中它不起作用,并不会带来任何结果。通常情况下,由于内存状态不同,同一个应用程序(内存溢出)可以在一台PC上运行并在另一台PC上崩溃。

答案 5 :(得分:1)

因为编译器进行静态检查。在您的第II部分,尺寸未知。这取决于您的输入长度。

我建议您使用STL字符串吗?