2015-10-04 30 views
0

我有以下代码将字符串追加到循环中的另一个。loop是由strcat导致的输出错误?

代码

#include<stdio.h> 
#include<string.h> 

int main(void){ 
     char src1[] = "name"; 
     int i; 
     for (i=1;i<=5;i++){ 
       strcat(src1,"opps"); 
       printf("loop times %d\n",i); 
     } 
       printf("now src1 is:%s\n",src1); 
     return 0; 
} 

要调试的代码,我添加printf语句代码和编译它。当我跑,我得到以下结果:

输出

循环次数1 循环次数0 循环次数1886416641 现在SRC1是:nameoppsoppsopps

我的问题是:“为什么printf环1886416641次?“而且,结果也不是我所期待的。有人能为我澄清这件事吗?

+0

您正在写出界限。在这种情况下,你正在覆盖循环计数器。 – EOF

+0

而不是“结果也不是我期待的”,更有用于发布预期内容。 – chux

回答

3

只有5个字节分配给str1strcat将访问出界,然后它可能会导致未定义的行为。

1886416641只是偶然得到。

您必须分配足够的内存给str1以获得正常结果。
示例:char src1[32] = "name";

+2

'1886416641''很难*意外:它是'0x70706F01',所以'ascii'ppo'\ 1''。这意味着您可以从中找出OP的机器排序。 – EOF

+0

谢谢,我已经将内存空间扩展到了S1,它现在可以工作。 –

3

您的src1[]不够大。当你追加第二个“opps”时,它会覆盖i。值1886416641是十六进制70706f01:0x70 ='p',0x70 ='p',0x6f ='o'。

编译器已舍入到下一个32位机器字。在字节的堆栈的样子:

start:  loop1 loop2 
src1[]: 
    n 
    a 
    m 
    e 
    \0  o 
    <fill> p 
    <fill> p 
    <fill> s 
i: 
    00  \0 o 
    00  00 p 
    00  00 p 
    01  02 s 
        \0 

(堆栈不准确;一些元素实际上颠倒 - 使用它作为一个例子)

+0

要清楚的是,“当你追加第二个”opps“时,它会覆盖i”是'srtrcat()'写入src1 []'之外的未定义行为的例子。它确实解释了OP的结果 - 这可能在另一天/平台上有所不同。 – chux

1

我想补充一点细节已经存在的答案,因为每man pagestrcat()

char *strcat(char *dest, const char *src);

strcat()功能追加src字符串到dest字符串,覆盖dest末尾的终止空字节('\ 0'),然后添加终止空字节。字符串可能不重叠,**和dest字符串必须有足够的空间用于结果。如果dest不够大,程序行为是不可预测的; [...]

如果您的最后一个字符串的长度超过目标的长度,您将访问导致undefined behavior的超出限制的内存。

在您的代码中,src1从初始化字符串的长度获取其大小。在以后某个时候,如果你想存储更长的一个,你需要在一开始分配更多的存储空间,像

char src1[128] = "name"; 

或相似。