事例1(转)
在程序中多次用的strcat函数,但是有时候编译通过,但是执行时却出现了错误。为了进一步了解strcat函数的使用,我首先写了这样的一个测试程序:
main()
{
char *Temp=(char *)malloc(sizeof(char)*200);
Temp="strcat";
char *Append=" a test program!";
strcat(Temp,Append);
printf("%s\r\n",Temp);
return 0;
}
{
char *Temp=(char *)malloc(sizeof(char)*200);
Temp="strcat";
char *Append=" a test program!";
strcat(Temp,Append);
printf("%s\r\n",Temp);
return 0;
}
这个程序,从感觉上没有错误,而且编译也不会出现错误,但是就是运行时却出现了错误,错误的地方就是在strcat这个函数处。刚开始百思不得其解,后来恍然大悟,所以就把我如何理解和处理的过程写在这里,以备以后查阅。
1、分析原因
程序错误的原因:内存不允许写入。我想到strcat要有足够的空间来保存要连接的两个字符串,而我开辟的200个字节的空间怎么会容不下这几个两个字符串。原因肯定不是空间不够,我把Temp改成定义为变量,ok可以通过。难道是strcat的第一个参数不能为指针变量,我仔细看了函数的说明没有这样的要求,所以也不是这个问题。
后来,我单步运行程序,发现了问题的症结所在。在定义了一个基类型为char类型的Temp指针变量并给他分配了200个字节的空间,但是执行到下一行就出现问题了Temp的值变了。这个原因我当时没有想到,后来仔细想想自己曾经总结过,是因为后面的字符串被当做了字符串常量,存储到了常量区,而Temp存储这个常量区首字符地址,所以根本就不是动态分配的空间。而后面strcat试图将一个字符串写入到一个常量区,所以出现了不允许写入的问题。
原因找到了,下面就是如何解决这个问题了。
2、问题解决
为了解决这个问题,我想出了两个解决方案:
为了解决这个问题,我想出了两个解决方案:
2.1、将strcat的第一个参数定义为数组,这样就避免了其在常量区的问题,问题得到了解决,哈哈,有点得意忘形了。有人问我习惯使用指针存储字符串怎么办?
2.2、没有关系,也是有解决的办法的,使用指针,并给其分配足够的空间,下面就是赋值的问题,如果不采用像上面的赋值方式那样就可以了,但是如何把一个字符串写到一个已分配的空间。我想到了strcpy这个函数,他可以把你的字符串写入到你给他分配的空间里去。
问题总算解决了,困扰了我几天的问题终于算搞明白了,是否一点问题都没有了,还有待于以后发现。
事例2:
在vc6中编程如下函数:
- #include "stdafx.h"
- #include
- #include
- using namespace std;
- int main(int argc, char* argv[])
- {
- char *p="abcde";
- int l=strlen(p);
- char *s="12345";
- strcpy(p,s);
- strcat(p,s);
- return 0;
- }
编译时可以通过,运行时却会出现access violation,这个错误的意思是说访问了一块已经失效的内存,究其原因,char *p="abcde",这一行在执行时,"abcde"(字符串常量)是位于文字常量区,这个区域的内容是不能修改的,而p这个指针变量是位于栈区,也就是说p指向了文字常量区的一个字符串。下面一行char *s的意义相同。
当在执行strcpy(p,s)时,它试图将p所指向的一块内存区域中的内容修改,而这是不可能的,所以会出现上面的那个错误,在执行strcat(p,s)时,它也是试图在修改文字常量区的内容,所以会错误。
当改成以下代码时就不会出现错误:
- #include "stdafx.h"
- #include
- #include
- using namespace std;
- int main(int argc, char* argv[])
- {
- char *p="abcde";
- int l=strlen(p);
- char *s="12345";
- //strcpy(p,s);
- //strcat(p,s);
- char a[]="abcde";
- char b[]="12345";
- char c[6];
- strcat(a,b);
- strcpy(c,b);
- return 0;
- }
此时就不会出错,因为char a[]="abcde"和char *p="abcde"它们的意义是完全不同的,前者的指针变量a是在栈区的,它所指向的"abcde"也是在栈区的,也就是说,a所指向的内存中的内容是可以被修改的。strcat(a,b)的意义也是类似的。
3,strcpy用法:
#include <string.h>
#include <malloc.h>
int main()
{
const char *b ="abc";
char *a = NULL; //这个指针要先分配空间
a=(char *)malloc(10000);
strcpy(a,b);
printf("%s",a); //输出字符串的形式应该是%s
free(a);//别忘了 释放内存
return 0;
}