栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > C/C++/C#

C++关于字符串的一点注意事项

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++关于字符串的一点注意事项

之前在给字符数组分配堆空间时出现了堆访问越界的问题。

经过一番查找,发现是对字符串的strlen、sizeof和字符串末尾结束符没理解清楚,现在趁这个空隙捋一捋。

一.字符串读取默认是会以''结尾的。

首先要知道strlen函数读出来的字符串长度是以在哪个位置上读取到''作为字符串的终止标志的。

1.举例1:

本质为分配在常量区

int main()
{
    char* s = "123 45";//在字符串中间人为插入''
    cout << strlen(s) <<  "  " << sizeof(s) endl;
    for (int i = 0; i < 8; ++i)cout << s[i] << endl;
    return 0;
}

1) 观察输出结果,发现 strlen只读取了前三位1、2、3的长度,这说明strlen的读取规则是以第一次出现的''作为字符串结尾的。

2)但是实际上为"123 45"这个字符串开辟了8个字节,分别存储的{ '1', '2' ,'3', '', '4', '5' , ''};

注意系统会为"123 45"这个字符串最后再多分配一个''

3) 除此之外,还有一个需要注意到的:sizeof并不会正确读取这种情况下字符串的正确长度,只是读出一个字符指针的地址长度。

 2.举例2:

本质为分配在栈区

int main()
{
    char s2[5]{ '1','2','3','','5' };
    cout << strlen(s2) << "  " << sizeof(s2) << endl;
    for (int i = 0; i < 5; ++i)cout << s2[i] << endl;
    return 0;
}

以字符数组的形式分配字符串 ,strlen函数同样是以''结尾作为结尾的。但是这时候的sizeof能正确读取到实际的字符数组的长度。

 3.举例3:

本质为分配在堆区。

int main()
{
    
    char* s3 = new char[6]{ '1','2','','3','4','5' };
    cout << strlen(s3) << "  " << sizeof(s3) << endl;
    for (int i = 0; i < 5; ++i)cout << s3[i] << endl;
    return 0;
}

 同样,分配在堆区的情况strlen也是以读取''作为结尾的。并且sizeof也只是读取到了字符指针的地址长度。

二、总结

如果要安全使用字符数组去表示字符串时,那么最后一位一定不要将其赋值,因为默认为字符数组分配的值便是''。最后一位不赋值能让strlen函数正确读取到有效的字符串长度。

1.举例1:
int main()
{
    
    char* s3 = new char[7]{ '1','2','3','4','5' };
    cout << strlen(s3) << "  " << sizeof(s3) << endl;
    for (int i = 0; i < 5; ++i)cout << s3[i] << endl;
    return 0;
}

数组在'5'后面没有赋值了,因此系统的默认分配是''。因此读出的有效长度是5。

如果占用了最后一位的话呢?

int main()
{
    char* s3 = new char[5]{ '1','2','3','4','5' };
    cout << strlen(s3) << "  " << sizeof(s3) << endl;
    for (int i = 0; i < 5; ++i)cout << s3[i] << endl;
    return 0;

}

 

 这时候strlen读出来的长度是22,这可能是一个随机的值。如果我们采用的strlen读出的值作为数组长度那就会产生读取越界的问题了。

 2.举例2
int main()
{
    char s4[5]{ '1','2','3','4','5' };
    cout << strlen(s4) << "  " << sizeof(s4) << endl;
    int n1 = strlen(s4);
    for (int i = 0; i < n1; ++i)cout << s4[i] << endl;
 }

分配在栈上的情况同理。

不正确地使用字符数组容易造成一些不易察觉的但是严重的问题,这是值得注意的。 

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1037149.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号