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

news2024/12/23 6:06:47

目录

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没有,兼容性低;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/66365.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

五年数据库专家,带你深入高性能 MySQL 架构系统,不要等到面试再追悔莫及

MySQL 作为互联网中非常热门的数据库&#xff0c;在高并发业务场景下&#xff0c;一条好的 MySQL 语句能为企业节省大量的运作时间和成本&#xff0c;这也是为何互联网大厂面试官最爱考察数据库底层和性能调优的原因。因此&#xff0c;了解其底层原理和架构的设计非常重要&…

2022年全球城市变迁研究报告

第一章 全球城市概述 全球城市 (Global City)&#xff0c;又称为世界城市 (World City)、国际大都市或国际都会城市&#xff0c;是指在财富、社会、经济、文化及政治层面直接影响全球事务的城市。近年来&#xff0c;随着全球化的扩张&#xff0c;城市文明与软实力的影响达到鼎…

redis的key过期事件不建议实现延时消息的原因

官网的解释 https://redis.io/docs/manual/keyspace-notifications/#timing-of-expired-events 简单的意思就是不能保证时效性&#xff0c;key过期事件可能会往后推个几分钟才触发&#xff0c;特别是数据量越来越大的时候。 而且一旦客户端处理失败&#xff0c;这个事件也不…

Linux 将 /home 目录与 / 根目录磁盘合并

1. Linux 下的 /home 目录与 / 目录 一般情况下进入 Linux 系统下的 / 目录&#xff0c;会看到如下目录列表。 [rootlocalhost /]# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var可以看到其中包含 home 目录&…

SpringBoot实现WebSocket

一、什么是websocket WebSocket是HTML5下一种新的协议&#xff08;websocket协议本质上是一个基于tcp的协议&#xff09; 它实现了浏览器与服务器全双工通信&#xff0c;能更好的节省服务器资源和带宽并达到实时通讯的目的 Websocket是一个持久化的协议 二、新建SpringBoot工…

STM32读保护的解除和出现的原因,使用串口和ST-LINK Utility解除读保护

STM32读保护的解除和出现的原因&#xff0c;使用串口和ST-LINK Utility解除读保护STM32读保护读保护保护出现的现象出现的原因读保护解决方法1、重新下载CH340驱动2、FlyMcu串口下载软件接触读保护使用STM32 ST-LINK Utility软件解除读保护注意STM32读保护 读保护保护出现的现…

4-(1,2,2-三苯基乙烯基)苯甲醛;​CHO醛基偶联AIE材料

中文名 4-(1,2,2-三苯基乙烯基)苯甲醛 英文名 4-(1,2,2-triphenylvinyl)benzaldehyde 4-(1,2,2-三苯基乙烯基)苯甲醛物理化学性质 分子式 C27H20O 分子量 360.455 质量 360.151428 AIE聚集诱导发光材料的特点&#xff1a; 1.在固态下有强发光特性&#xff08;粉末或高浓度&am…

【Linux03-基本工具之GCC】Linux下的C语言编译器

前言 接上篇&#xff0c;继续学习基本工具。 三、gcc 是什么 Linux下的C语言编译器&#xff08;C的编译器是g&#xff0c;用法选项基本一样&#xff09;。 既然是编译器&#xff0c;我们就再来加点餐…… 链接其实分为两种类型&#xff1a;静态链接和动态链接&#xff0…

内切相减原理绘制CAD图形

CAD中的内切相减的原理你们知道是什么意思吗&#xff1f;这个就需要用CAD实际图形的绘制过程来理解了&#xff0c;这个图形就用到了这个&#xff0c;还用到了CAD直线、修剪、圆等命令共同绘制出来。 目标图形 操作步骤 1.使用CAD直线命令绘制一条长度30的垂直直线AC&#xff…

自定义 HandlerMethodArgumentResolver 怎么和默认HandlerMethodArgumentResolver进行隔离的?

工作中&#xff0c;想对一些参数进行非空默认值的操作。 DefaultValueIfNull("1000") 这个就是&#xff0c;如果为null&#xff0c;那么就默认值填1000。 操作起来。 1.自定义HandlerMethodArgumentResolver Component public class DefaultValueIfNullResolver…

seata-server-1.5.2的部署

使用的是nacos和mysql数据库&#xff0c;简单部署在Win10上&#xff0c;Linux上配置修改相同&#xff0c;启动命令不同。 找到 seata-server-1.5.2\seata\conf目录下的application.yml和application.example.yml 编辑 application.yml&#xff0c;原始版本如下&#xff1a; s…

RocketMq: Windows环境-单机部署和伪集群、集群部署

关于默认端口 broker的默认端口有3个,10911, 10912, 10909。 10911是remotingServer使用的监听端口,remotingServer主要处理以下三类消息: producer发送的消息 conumser在消费失败或者消费超时发送的消息 consumer拉取消息10912是主broker用于监听从broker请求…

制作路由器openwrt安装及配置

Openwrt软路由安装配置1、 Openwrt软路由设备信息&#xff1a; <1>登录信息&#xff1a; IP&#xff1a;10.4.1.1 账号&#xff1a;root<2>设备配置&#xff1a; 主机名 Openwrt 型号 ASUSTeK COMPUTER INC. Z9PA-U8 Series CPU 型号 Intel(R) Xeon(R) …

YOLO系列目标检测算法——PP-YOLO

YOLO系列目标检测算法目录 - 文章链接 YOLO系列目标检测算法总结对比- 文章链接 YOLOv1- 文章链接 YOLOv2- 文章链接 YOLOv3- 文章链接 YOLOv4- 文章链接 Scaled-YOLOv4- 文章链接 YOLOv5- 文章链接 YOLOv6- 文章链接 YOLOv7- 文章链接 PP-YOLO- 文章链接…

爬虫之selenium

目录 selenium介绍 基本使用 selenium用法 元素操作 等待元素被加载 元素各项属性 执行js代码 切换选项卡 浏览器前进后退 无界面浏览器 xpath的使用 简单介绍 selenium中使用 异常处理 登录获取cookie保存 动作链 打码平台使用(验证码破解) selenium介绍 由…

JavaScript -- 正则表达式及示例代码介绍

文章目录正则表达式1 正则表达式的介绍2 创建正则表达式3 通过整个表达式检查字符串是否符合规则4 正则表达式的基本语法5 提取符合规则的字符串6 例子正则表达式 1 正则表达式的介绍 正则表达式用来定义一个规则通过这个规则计算机可以检查一个字符串是否符合规则或者将字符…

python PyQt6 常用操作以及常见问题解决

因为需求需要写一个简单的Python GUI界面&#xff0c;期间遇到了一些问题&#xff0c;在这里记录下 安装PyQt6: pip install pyqt6使用QTDesigner绘制界面&#xff1a; 我使用Anaconda下载的pyqt6里已经自带了两种工具&#xff0c;下面只需要把工具导入到pycharm中&#xff0…

[附源码]计算机毕业设计旅游网的设计与实现Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

『Python学习笔记』使用Cython编程语言编译python文件

使用Cython编程语言编译python文件 文章目录一. Cython简介一. Cython编译2.1. 编译过程2.2. 环境安装2.3. disutils库2.4. 引入C源文件三. 总结参考文献一. Cython简介 Cython官网地址&#xff1a;https://cython.org/Cython的下载和安装&#xff1a;https://pypi.org/projec…

嵌入式分享合集117

一、获取STM32代码运行时间的技巧 测试代码的运行时间的两种方法&#xff1a; 使用单片机内部定时器&#xff0c;在待测程序段的开始启动定时器&#xff0c;在待测程序段的结尾关闭定时器。为了测量的准确性&#xff0c;要进行多次测量&#xff0c;并进行平均取值。 借助示波器…