2013-04-26 65 views
2

下面的字符串是代码供应未空终止STRCPY

smem_dmp(char *name, char content[]) 
{      
     int i; 
     int len = strlen(content);  

     printf("%s\n\n", name); 

     for(i = 0; i < len; i++) 
     { 
      printf("%c\t%p\n", content[i], &content[i]);  
     } 

     printf("Done\n\n"); 
} 

print_bar() 
{ 
    printf("********************************************************************\n"); 
} 

int main(int argc, char *argv[]) 
{ 
    char a[16]; 
    char b[16]; 


    strcpy(a, "abcdefghijklmnop"); 
    printf("a = %s\nb = %s\n\n",a,b); 

    smem_dmp("A", a); 
    smem_dmp("B", b); 

    print_bar(); 

    strcpy(b, "ABCDEFGHILKLMNOP"); 
    printf("a = %s\nb = %s\n\n",a,b); 

    smem_dmp("A", a); 
    smem_dmp("B", b); 

    system("PAUSE");  
    return 0; 
} 

通过观察A和B驻留在内存中我曾发生了什么事。复制到b的字符串不是空终止的。这导致a的内容被删除,因为b在内存(0028FF30)之前位于(0028FF20)。

发生了什么事? strcpy(b,“string”)在经过堆栈帧变量的所有内存之后才停止吗?对不起,如果我不使用正确的术语。 :)

+1

你的数组'a'太小了。它至少需要17个元素。 – 2013-04-26 13:58:47

+0

谢谢。我知道。这比理解代码更重要的是理解安全性。 – user84628 2013-04-26 14:01:10

+1

是的,它会继续复制字节,直到它在任何正在访问的随机存储器中达到零字节,或者它到达不可访问的存储器并导致存储器故障。如果布局如您所说,那么如果在它崩溃之前它到达那里,那么它最终会在其他字符串中乱写。这些都不是由任何标准定义的,它只是常用的实现。 – jcoder 2013-04-26 14:06:40

回答

6

这是怎么回事? strcpy(b,"string")不会停止,直到它已经通过堆栈帧变量的所有内存?

strcpy复制字节直到它在源中找到一个0字节。将其复制到目标,然后返回strcpy。 (如果目标不是大到足以容纳源包括0 - 终止,该行为是不确定的,但除非你得到一个分段错误,那是你可以依靠在发生什么样的做法。)

所以

strcpy(b, "ABCDEFGHILKLMNOP"); 

副本17个字节 - 的16个字母和0终止子 - 从字符串文字到阵列b,其中仅包含16个元素。这意味着0终结符被写入数组b末尾的一个元素。在你的情况下,这是a中的第一个字节,而strcpy(b, "ABCDEFGHIJKLMNOP");实际上使得a包含一个空字符串。

2

"abcdefghijklmnop"尺寸为16和你a数组的大小为16应该是17(16 + 1空终止charachter)