2013-10-07 30 views
6

的大小采取以下程序:strcat的目标数组

#include <iostream> 
#include <cstring> 

using namespace std; 

int main() 
{ 
    char a[8] = "Hello, "; 
    char b[7] = "world!"; 

    strcat(a, b); 

    cout << a; 

    return 0; 
} 

注意ab有大小作为其指定的字符串相同。

documentation指出,要使strcat(a, b)正常工作,a需要足够大以包含连接的结果字符串。

尽管如此,cout << a显示"Hello, world!"。我是否进入未定义的行为?

回答

11

“我是否进入未定义的行为?

是。 []结尾处的区域已被写入。它的工作,这次,但可能属于别的东西。

在这里,我使用结构来控制存储器的布局,并证明它:

#include <iostream> 
#include <cstring> 

using namespace std; 

int main() 
{ 
    struct S { 
     char a[8]; 
     char b[5]; 
     char c[7]; 
    }; 

    S s; 
    strcpy(s.a , "Hello, "); 
    strcpy(s.b , "Foo!"); 
    strcpy(s.c , "world!"); 


    strcat(s.a, s.c); 

    cout << s.a << endl; 
    cout << s.b << endl; 

    cin.get(); 

    return 0; 
} 

此输出:

Hello, world! 
orld! 

代替:

Hello, world! 
Foo! 

的的strcat()具有跺脚遍布b []。

请注意,在现实生活中的例子这样的错误可能是微妙得多,带领你想知道为什么完全无害的函数调用250线后和好如初可怕。 ;-)

编辑:我也建议你使用strcat_s,代替?或者,甚至更好,性病::字符串:

#include <string> 
#include <iostream> 

using namespace std; 

int main() 
{ 
    string a = "Hello, "; 
    string b = "world!"; 
    a = a + b; 
    cout << a; 
} 
+2

+1。对一个不太好的问题的好答案。 – Nawaz

+0

@Nawaz,对你有什么好*问题?它是一种促进你的知识吗?无论如何......谢谢Arkady,非自恋的,彻底的答复。 – Raptor

+0

@JosuéMolina:问问你自己:什么是你*不那么好的*问题? – Nawaz

3

上午我进入未定义行为?

是。


如果文档中说a需要足够大,以包含串联的结果字符串”,你为什么不只是相信吗?有什么可疑的?

1

这是正确的....行为是不确定的。仅仅因为你得到了答案并不意味着它不会在下一次崩溃,因为数组a太小。

2

在你的程序中,数组a是没有大到足以容纳结果。因此,你的代码是错误的,应该修复。用标准的话说,你确实进入了未定义的行为,这意味着它可能工作,或者它可能不会...

+0

它可能工作损坏,为一点,你可能会得到意想不到的结果。我已经看到了这个错误运行正常,直到有电话到std :: vector的 ::的push_back()中途在一个完全不同的源文件中的循环失败。结果发现这种错误就是问题:部分矢量被糟糕的strcat()覆盖。 – Arkady

2

strcat做什么是对锡即如是说。将b复制到a的末尾,而不必考虑已经存在的数据。因为这两个变量都在一个接一个地工作。但尝试

#include <iostream> 
#include <cstring> 

using namespace std; 

int main() 
{ 
    char a[8] = "Hello, "; 
    int i = 10; 
    char b[7] = "world!"; 

    strcat(a, b); 

    cout << a << i; 

return 0; 
} 

而且,由于你的筹码已被strcat