• str(n)cpy的注意事项以及memset的简单使用


    目录

    strcpy

    strncpy

    memset


    前言:因为C语言不能像C++的string那样重载=、+等运算符,所以C语言提供了用于字符串拷贝的函数strcpy与strncpy,但是这两个函数都存在着一些问题;

    我们需要先知道,字符串的结束标志是\0,如果没有\0不能称为字符串;

    strcpy

    我们先看strcpy函数

    char* strcpy(char* dest, const char* src);

    注意使用strcpy需要在第一行加上#define  _CRT_SECURE_NO_WARNINGS一定要是第一行,其他地方不行;

    然后输出一下字符串:

     

    没有问题,我们单个输出name数组的每个成员的ascii码值试一下:

    运行:

     

    我们可以看到,因为我们并没有初始化,所以strcpy函数是帮我们把hello后的第六个元素置为0了,因为有\0才是字符串嘛; 

    如果我们的name只有五个元素,但是我们依旧赋值给他hello,那么还会不会补充\0呢?

    如下:

    程序直接崩掉了;

    所以我们如果给字符串使用strcpy的时候一定不要忘了给\0留个位置; 

    可能大家会问,为什么C语言的库函数strcpy没有考虑到内存越界的问题呢?这个在文章的最后我会告诉大家;

    strncpy

    我们再来看看strncpy,这个函数的声明是这样的:

    char* strncpy(char* dest, const char* src, const size_t n);

    就是比strncpy多了一个参数,用于指定拷贝多少内容;

    先看代码,这是第一种拷贝方式,第三个参数比第二个参数要长的时候:

    运行一下:

     

    我们直接cout输出一下:

     

    没有任何异常; 

    下面进行第二种拷贝方式:

    运行: 

    我们再用cout<<输出一下整个字符串,想必大家已经猜到结果了:

    因为内存越界,读取到了一堆垃圾值,cout<<输出直到遇到了\0才停下来;

    可能有人会问:那是不是第一种拷贝场景比第二种常见很多?

    实际上并不是的。

    那么怎么样尽量避免这种问题,让strncpy安全一点呢?

    因为在实际开发中,我们很多时候不知道src字符串的长度,只知道dest字符串的长度,所以我们的第三个参数一般都是填dest字符串长度-1;

    就比如上面,如果我们的name长为11,那么第三个参数就填10;这样的话如果src比10短,那么strncpy会自动填充几个\0,如果src比10长,那么他也只能拷贝10个元素,我们在结尾将name[10](最后一个元素)手动赋值为\0不就安全了嘛;也避免了内存越界的问题;

    memset

    其实在实际开发中,还有一种常用的方式:memset();

    void *memset(void *str, int c, size_t n)

    第一个参数就是待初始化内存块的首地址;

    第二个参数是将这块地址中的值初始化为什么?

    第三个参数就是初始化内存块的大小;

    我们使用这个函数将name的元素全部初始化为0:

    运行一下:

     

    可以看到,除了我们指定的那三个元素外,其他的都被memset置0了;这样如果输出的话,遇到\0就会结束,所以肯定没问题,我们输出一下:

     

    这样也就成功解决了; 

    为什么str(n)cpy库函数没有判断内存可能会越界的问题?

    因为不论是strcpy还是strncpy他们的参数都是字符串的起始地址,没有让传入目标字符串的长度,所以他们根本无法判断你的dest字符串到底有多长,也就没有办法判断内存越界问题了;

    不过我们可以自己做一个比较安全的strcpy函数,加上目标字符串长度参数,或者用其他方式让内存不能越界,感兴趣的小伙伴可以自己尝试做一下,当然网上也有很多案例,可以借鉴,为自己的框架如虎添翼;

    注意事项

    1、字符串在每次使用之前都要初始化,初始化最好的方法就是memset,减少入坑的可能,注意是每次,不是第一次;

    2、使用strncpy的时候,尽量把第三个参数写成sizeof(目标字符串)-1,也能避免很多入坑的可能;

    3、在VS中,如果要使用C标准字符串操作函数,要在源代码文件的最上面#define _CRT_SECURE_NO_WARNINGS,当然VS还提供了一些函数可以解决字符串安全问题,比如strcpy_s,strcat_s,但是不建议使用,因为VS有,但是Linux没有,兼容性低;

  • 相关阅读:
    C++ set容器
    Google Earth Engine(GEE)—— LULC 土地分类
    exe文件运行后无输出直接闪退如何找解决办法
    CAN总线数据采集工具PCAN的使用教程
    在微信小程序上做一个「博客园年度总结」:小程序部分交互效果实现
    电脑新加的硬盘如何分区?新加硬盘分区选MBR还是GPT
    LangChain支持哔哩哔哩视频总结
    DolphinScheduler 进阶(工作流传参)
    (JavaEE)线程的状态
    WEB攻防-ASP安全-ASP后门植入连接
  • 原文地址:https://blog.csdn.net/qq_52572621/article/details/128203112