字符串越界问笔试常见题

1、
#include<string.h>
int main()
{
   char string[10]; //     甚至 string[9]都可以
   int i;
   char *str1="0123456789";   //  这里实际还要添加 '\0',因为 \0是C++中字符串的结尾标志,存储在字符串的结尾。比如char cha[5]表示可以放4个的数组,由于c/c++中规定字符串的结尾标志为'\0',它虽然不计入串长,但要占内存空间
   strcpy(string,str1);   // 相当于把 0123456789 还有 '\0' 共 11个字符存入 10个中,放不下只好越界,况且C语言编译器是不检查越界的</span>
     for( i=0;i<10;i++)
	   printf("%c",string[i]);
   printf("\n");
   printf("%c",str1[10]);

}

strcpy()函数是对C风格字符串进行操作的函数,

上例的str1是一个字符串,C风格的字符串以‘\0’结束,

所以str1虽然看上去只有10个字符,但实际上应加上‘\0’,即应为11个字符,

而string数组只有10个元素,而strcpy()函数的实现是遇'\0'而停止拷贝,所以拷贝时实际上是把‘\0’也进行了拷贝,这就导致string数组越界拷贝

当然有时候运行正常,有时候是不正常的,这取决于 越界后后面的 string[10],对程序有没有危险。

注意: strcpy()函数是多C风格的字符串进行拷贝,即遇‘\0’而停止拷贝

——————————————————————————————————————————————————————————————

2、

 

#include<stdio.h>
#include<string.h>
int main()
{
   char string[10], str1[10];
   int i;
	for(i=0; i <10;i++)
	{
	  str1[i] = 'a';
	}


    printf("%d\n",&str1[10]);   // 这个地址在内存里是 1245042,也就是 str1[10]的地址,当然str1[10]坑定算越界了, 
	printf("%c\n",*(char *)1245042); // 这里用 指向 char类型的指针来 查找 str1[10]里面究竟存的是什么,这里存的是'?'
                                    // 当然 1245041 存的是 a 
	strcpy(string, str1);
   
	for( i=0;i<10;i++)
	   printf("%c",string[i]);
   printf("\n");
   printf("%c",str1[10]);


}
//
//上例说过strcpy()函数是多C风格的字符串进行拷贝,即遇‘\0’而停止拷贝,而本例中str1不是C风格的字符串,而是一个char数组,
//不是以'\0'结束的,所以strcpy()函数会一直进行拷贝直到遇到第一个'\0'才结束拷贝,所以string越界是必然的,因为我们不知道什么时候遇到'\0'。


  运行不起来

 

 

————————————————————————————————————————————————————————————————————

3、

 

#include<stdio.h>
#include<string.h>
int main()
{
    char *str1="123456789" ;  //指针字符串的好处是 会自动添加 字符串结束符 '\0',也就是正好 10 个数了
	char string[10];   
	if(strlen(str1) <10)     // strlen 计算的是有效可见的字符长度,自然'\0'是不算的,所以这里为 9 ,10个放10个没有问题
	{
	strcpy(string, str1);     
	}
	printf("%s",string);

}

但是如果把 char *str1="123456789" 改为 0123456789 ,那么就是10个字符再加上 '\0' 共11个字符
,那么就错了。

 

————————————————————————————————————————————————————————————————————————————————

 

posted on 2015-10-15 21:33  无悔这一生。  阅读(624)  评论(0编辑  收藏  举报

导航