现在的位置: 首页 > 综合 > 正文

strcat()连接两个字符串的问题分析

2013年09月20日 ⁄ 综合 ⁄ 共 1300字 ⁄ 字号 评论关闭

 一、发现问题

有三个小程序:

(1)用两个指针变量指向字符串

#include <iostream>
using namespace std;
#include <stdio.h>
#include <string.h>
 
int main()
{
        char *p = "welcome ";
        char *q = "to the house";
        strcat(p, q);
        cout<<p<<endl;
        return 0;
}

调试运行,会出现中断,中断位置在strcat.asm文件中的main_loop处:

同时,弹出一个中断信息对话框:

(2)第一个用未指定大小的字符数组存储字符串,第二个用指针变量指向字符串

#include <iostream>
using namespace std;
#include <stdio.h>
#include <string.h>
 
int main()
{
        char p[] = "welcome ";
        char *q = "to the house";
        strcat(p, q);
        cout<<p<<endl;
        return 0;
}

调试运行,会出现中断,中断位置在主函数的最后处:

同时,弹出一个中断信息对话框:

(3)第一个用指定大小的字符数组存储字符串,第二个用指针变量指向字符串

#include <iostream>
using namespace std;
#include <stdio.h>
#include <string.h>
 
int main()
{
        char p[50] = "welcome ";
        char *q = "to the house";
        strcat(p, q);
        cout<<p<<endl;
        system("PAUSE");
        return 0;
}

调试运行,没有错误,运行结果如下:

二、分析问题

        仔细查看这三个小程序,你会发现它们都是为了完成同一个功能:将字符串"welcome "和"to the house"连接起来,它们实现的不同之处在于字符串"welcome"的存储方式。第一个和第二个程序调试运行都出现中断,而第三个运行正常。这是为什么呢?我终于弄明白了。

        首先,要彻底理解strcat()函数。

                其原型为 char *strcat(char *a, const char *b);

                其作用为去掉字符串a的结束符"\0"后,将字符串b连接到a的后面,并存储到a中。

        因为strcat()是将a和b连接起来后存到a中,那么a就要有足够的存储空间,否则就会溢出。

        第一个程序中,采用的指针变量p存储第一个字符串。运行过程中,指针变量p所指向的内存是分配在堆中的,且只分配了足够其指向的内容的内存。将q连接到p后,自然p是没有其他空间给q了,所以出现了内存写入冲突而中断。

        第二个程序中,采用未指定大小的数组p存储第一个字符串。运行过程中,数组p存放在栈中,因其未指定大小,那么在初始化时,系统就默认其指定大小为初始化字符串的长度。将q连接到p后,p也没有多余的空间给q,所以就出现了上述图中的错误。

        而第三个程序中,为数组p预先分配了50,其有足够多余的空间容纳下q,所以运行无错误。

抱歉!评论已关闭.