C++中strcpy函数的使用注意事项

在C语言或者C++的开发过程中,我们经常会使用strcpy这个函数,甚至很多教材都会使用strcpy这个函数,strcpy这个函数确实也挺好用的,但是它在使用过程中稍微不注意,就会被坑到。

1、问题代码分享

是什么样的坑呢?我们来看看下面这段代码:

char l_cData1[5], l_cData2[5];
string l_strData3 = "123456789";

memset(l_cData1, 0x00, sizeof(l_cData1));
memset(l_cData2, 0x00, sizeof(l_cData2));

strcpy(l_cData1, l_strData3.c_str());

2、问题代码分析

以上这段代码里面,strcpy这个函数会把“123456789”这串长度为10的数据拷贝到l_cData1这个长度为5的数组里面去,同时不会报错。

这样看好像我们确实已经实现了数据拷贝的目的,但实际这样的操作有可能会造成你的程序coredump崩溃。

因为“123456789”这段数据,前面“12345”的5个字节拷贝到l_cData1中,但是后面“6789”的数据却拷贝到了l_cData1外的地方,造成了数组拷贝越界,严重的情况下,后面“6789”的数据可能会被复制到同一个程序中的其他变量数据,导致了其他变量数据被改写。

这种其他变量数据被改写,但是却不会导致程序coredump崩溃的问题是很难排查出来的。笔者曾经在A业务中用strcpy拷贝了一个数据,结果导致了B业务结算时数据不会,就好比你在QQ空间上改了一个业务数据,结果QQ音乐的数据异常了,看起来毫不相关,但是实际上就是strcpy导致了数组拷贝越界导致的。

再回到上面那段问题代码,如果l_cData1和l_cData2这两个变量数组在内存中的存储是连续的,那就出现以下这种情况,l_cData2的数据被改写:

//想象中strcpy使用后的情况,l_cData2的数据没变化

l_cData1[5] = {'1', ‘2’, '3', '4', '5'};
l_cData2[5] = {0, 0, 0, 0, 0};

//实际中strcpy使用后的情况,l_cData2的数据被改写
l_cData1[5] = {'1', ‘2’, '3', '4', '5'};
l_cData2[5] = {'6', ‘7’, '8', '9', 0};

3、问题代码排查

那遇到以上这种数据被改写,但程序又不会崩溃,定位不到问题的情况,该怎么办?

这时候其实可以使用内存泄露检测工具,在linux上有valgrind这个工具,笔者用过,挺好用的,这个工具在你程序运行时候检测你的内存访问越界、内存泄露问题。

4、问题代码杜绝

当然了,最好的问题处理方式,还是要从根源上去解决的。那就是不要用strcpy这个函数,可以用strncpy这个函数代替,代码如下:

char l_cData1[5], l_cData2[5];
string l_strData3 = "123456789";

memset(l_cData1, 0x00, sizeof(l_cData1));
memset(l_cData2, 0x00, sizeof(l_cData2));

strncpy(l_cData1, l_strData3.c_str(), 5);

我们看看strncpy这个函数的定义:

//表示把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。
char *strncpy(char *dest, const char *src, int n);

也就是说strncpy这个函数,他可能指定你最多能复制多少长度的数组,防止你访问越界。

5、问题代码延伸

其实不关strcpy有这种数组拷贝越界的隐患,还有sprintf、strcat、strcmp都有这种隐患,最好使用snprintf、strncat、 strncmp代替。

否则有时候会出现一些看起来很玄学的问题,很难排查,但实际上,这些看似玄学的问题,其实是有科学依据的,只是我们很难看到。

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值