请问这个程序的结果为什么发生错误
写了一个两个字符串连接的程序 为什么输出的str2前面少掉了一个 'h ' 本来应该输出‘sasafasdheoheo’和 'heoheo '的 结果输出的是‘sasafasdheoheo’和 'eoheo ' 还有为什么这程序在vc++6.0里面能编译不能运行 说什么存取错误 但是能在turbo c下面正常运行。
#include <conio.h> /* 此头函数请不要删除 */
#include <stdio.h>
/*连接两个字符串*/
void strconct(char *, char *);
void main ()
{
char *str1= "sasafasd " ;
char *str2= "heoheo " ;
printf( "%s\n%s\n ",str1,str2);
strconct(str1,str2);
printf( "%s\n%s\n ",str1,str2);
getch(); /* 此语句请不要删除*/
}
void strconct(char *t, char *s)
{
while(*t!= '\0 ')
*t++;
while((*t=*s)!= '\0 ')
{
*t++;
*s++;
}
}
[解决办法]
str1和str2是两个指向了常量字符串的指针,常量字符串是不能被写的。
故*t = *s,就会在运行的时候报这个错。
str1和str2指向的两块字符串内存,编译器处理的时候,它们是相邻的。
当你把str2直接接在str1后面的时候,实际上因为str1最后有一个0,所以*t = *s,实际上是把str2的字符串往前移了一个字节,所以,str2会少一个 'h '
[解决办法]
char型指针 str2 指向的地址并没有改变 开始是指向heoheo中的 h
调用函数后 heoheo 都向前移动了一个字节
str2 指向的地址就是 第2个字母 e
[解决办法]
char *str1= "sasafasd " ;
char *str2= "heoheo " ;
内存: "sasafasd\0heoheo\0 " str1指向第一个s,str2指向第一个h
strconct操作后,内存: "sasafasdheoheo\0\0 " str1,str2指向地址不变
字符串输出就这样了
如果两个字符串分配不连续,那问题就严重了,总之,这样的写法是错误的
vc和多数编译器都把字符串常量存放在常量区,内容是不能修改的,相当于加了const
通常,
char str1[20]= "sasafasd " ;/*长度大于两字符串长度相加*/
char str2[]= "heoheo " ;
strconct(str1,str2);
[解决办法]
如下图所示:
str1 |str2 //在栈上连续分配了两个字符串,大小分别为9(str1)和7(str2)
0123456789abcdef //str1的起始位置为0;str2的起始位置为9
sasafasd^heoheo^_ // '^ '表示字符串结尾的 '\0 '
sasafasdheoheo^ //调用strconct后的结果写入时实际上越过了字符数组str1的边界了
str1 str2
TC环境下没作越界检查,所以可执行。VC下则会导致非法访问内存