关于Linux C语言开发字符越界的问题
本人linuxC开发初级程序员一枚,为了能使自己更快的学习进步,开始记录自己工作和学习过程中遇到的一些问题,这是第一天笔记,希望能够坚持下来,以后可以用来回忆自己刚开始工作的岁月。话不多说,开始写一下今天解决的问题吧。
字符越界的问题已经遇到不止一次了,今天测试程序的时候再次发生问题,真是不应该。
经过一段时间的开发,也遇到了不少千奇百怪的问题,其中令我比较痛苦的即时字符串越界的问题,数组或串的越界访问是难以发现且相当危险的行为,下面就自己遇到的错误和网上查阅的资料进行一下总结,加深记忆,防止以后出现类似错误而影响开发效率,千万不要相信自己能有多高的记忆能力,还是留个笔记好。
字符串的存储格式有两种,一种是顺序存储结构,又成静态存储结构;另一种是链式存储结构,又称动态存储结构。静态存储有两个缺点,一个是需要预先定义一个串允许的最大字符格式。二是限定了串的最大字符个数,使串的某些操作如复制、连接等受到很大限制与影响。数组或串的越界访问是难以发现且相当危险的,因为它可能改变了其他存储空间的内容。
1,关于字符串变量操作中的越界问题
字符串变量是一个基类型为字符类型的数组变量,其定义的一般形式为:
char 数组名[元素个数]
在声明字符串变量时,可用字符常量进行初始化,如char name[30]="abcdefghihklmn";
这时编译程序会为字符串为题name分配30个字节的存储空间,并将”Zhongshan University”中20个字符的ASCII码存储在前20个字节中,然后在第21个字节中存放一个’\0’表示串结束,至于第22个至30个字节是什么内容是不关心的。字符串变量占用的存储空间大小与其中存放的字符串的长度之间没有相等关系,尽管name中存放的字符串长度为20,实际使用了21个字节,但它仍然占用着30个字节存储空间。
鉴于上述存储空间组织形式,在初始化字符串变量时一定要注意字符串长度不要超过其存储空间的大小
为了避免上述字符串越界错误,解决办法是:不必声明字符数组的长度,而由编译程序根据初始化的字符串常量的长度自动决定,如 char name[]="abcdefghijklmn";
2,关于字符串库函数操作的越界问题
与其他类型的数组一样,只可在声明字符串变量时用赋值运算作初始化,在其他地方不允许直接使用赋值运算,如:
char name[30];
name="abcdefghijklmn";
因为name实际上是一个常量指针,不可用赋值语句改变其值,即name不允许作为一个“左值”.
1)字符串复制函数
char * strcpy(char * str1,const char * str2);
功能:将str2指向的字符串复制到str1指向的位置中并返回str1。
注意:为str1分配的存储空间必须能放得下str2指向的字符串。
以下是初学者常犯的错误: char * str; strcpy(str,”Be careful.”); //可能引起严重的问题
因为str所指向的存储空间地址是不确定的,还没有让这个指针指向一块已分配到的存储空间。然而以下用法却是正确的:
char * str; str=”Be careful.”;
因为字符串常量已经分配了存储空间,赋值后指针str指向这一空间。另一用法也是正确的:
char str[20]; strcpy(str,”Be careful.”);
因为str已经静态地分配了20个字节的空间,所以可以将字符串常量复制到这一存储空间。注意:为str静态或动态申请的存储空间大小不可小于12个字节,否则会出现越界写入错误.
2)字符串连接函数
功能:将字符串str2连接到字符串str1后,形成一个新的字符串,原先str1的结束标记’\0’被取消,函数返回值为str1。
注意:为字符串变量str1分配的存储空间一定要足够大,能够容纳两个字符串连接后的新字符串。
执行传统的复制或连接函数是有风险的,因为str1所指字符串所分配的空间不够大时,指针str2所指字符串复制或连接过来就造成了越界错误。数组或字符串的越界访问是难以发现且相当危险的,因为它可能改变了其他存储空间的内容。