32. C 语言 安全函数( _s 尾缀)
本章目录
- 前言
- 什么是安全函数?
- 安全函数的特点
- 主要的安全函数
- 1. 字符串操作安全函数
- 2. 格式化输出安全函数
- 3. 内存操作安全函数
- 4. 其他常用安全函数
- 安全函数实例
- 示例 1:`strcpy_s` 和 `strcat_s`
- 示例 2:`memcpy_s`
- 示例 3:`strtok_s`
- 总结
前言
在 C 语言的编程中,缓冲区溢出是常见的安全问题之一。它发生在程序尝试将数据写入一个不足够大的缓冲区时,导致数据覆盖了相邻内存区域。这种错误不仅会导致程序崩溃,还可能导致潜在的安全漏洞,使攻击者能够通过精心设计的输入数据控制程序流,甚至执行恶意代码。
为了避免这类问题,C11 标准引入了一些 “安全函数”(通常称为 Annex K 函数),这些函数是传统 C 函数的增强版本,增加了缓冲区大小检查和错误处理机制,从而提升了程序的安全性。
本文将带您深入了解 C 语言中的安全函数,帮助您编写更加健壮和安全的代码。
什么是安全函数?
在 C 语言中,安全函数是指那些在执行字符串和内存操作时,显式检查目标缓冲区大小并报告错误的函数。它们的设计初衷是防止缓冲区溢出、访问越界等问题。安全函数通常返回一个 errno_t 类型的错误码,以便调用者能够检测是否成功执行。
安全函数的特点
- 缓冲区大小检查:安全函数需要明确传递目标缓冲区的大小,确保不会发生溢出。
- 返回值检查:大多数安全函数返回一个错误代码,可以通过检查返回值来判断是否成功执行。
- 错误处理:当缓冲区大小不足或者其他错误发生时,安全函数会尝试清空或初始化输出缓冲区,避免未定义的行为。
主要的安全函数
以下是 C 语言中一些常见的安全函数及其传统函数对比:
1. 字符串操作安全函数
-
strcpy_s:安全版本的strcpy,复制字符串并检查目标缓冲区的大小。errno_t strcpy_s(char *dest, rsize_t destsz, const char *src); -
strcat_s:安全版本的strcat,将源字符串追加到目标字符串末尾,并检查缓冲区大小。errno_t strcat_s(char *dest, rsize_t destsz, const char *src); -
strncpy_s:安全版本的strncpy,复制最多n个字符,并检查缓冲区大小。errno_t strncpy_s(char *dest, rsize_t destsz, const char *src, rsize_t count); -
strncat_s:安全版本的strncat,追加最多n个字符到目标字符串末尾,并检查缓冲区大小。errno_t strncat_s(char *dest, rsize_t destsz, const char *src, rsize_t count); -
strtok_s:安全版本的strtok,引入上下文参数,解决线程安全问题。char *strtok_s(char *str, const char *delim, char **context);
2. 格式化输出安全函数
-
sprintf_s:安全版本的sprintf,格式化输出到字符串时检查缓冲区大小。int sprintf_s(char *buffer, rsize_t sizeOfBuffer, const char *format, ...); -
snprintf_s:安全版本的snprintf,格式化输出时限制字符数并检查缓冲区大小。int snprintf_s(char *buffer, rsize_t sizeOfBuffer, const char *format, ...); -
vsprintf_s:安全版本的vsprintf,接收va_list参数列表,并检查缓冲区大小。int vsprintf_s(char *buffer, rsize_t sizeOfBuffer, const char *format, va_list argptr);
3. 内存操作安全函数
-
memcpy_s:安全版本的memcpy,复制内存时检查目标缓冲区大小。errno_t memcpy_s(void *dest, rsize_t destsz, const void *src, rsize_t count); -
memmove_s:安全版本的memmove,允许内存区域重叠,并检查目标缓冲区大小。errno_t memmove_s(void *dest, rsize_t destsz, const void *src, rsize_t count); -
memset_s:安全版本的memset,填充内存并检查目标缓冲区大小。errno_t memset_s(void *dest, rsize_t destsz, int ch, rsize_t count);
4. 其他常用安全函数
-
_itoa_s和_ultoa_s:安全版本的整数转换函数。errno_t _itoa_s(int value, char *buffer, size_t sizeOfBuffer, int radix); errno_t _ultoa_s(unsigned long value, char *buffer, size_t sizeOfBuffer, int radix); -
_strlwr_s和_strupr_s:将字符串转换为小写或大写的安全版本。errno_t _strlwr_s(char *str, size_t numberOfElements); errno_t _strupr_s(char *str, size_t numberOfElements);
安全函数实例
下面通过一些简单的示例,展示如何使用 C 的安全函数来提高代码的健壮性,避免缓冲区溢出问题。
示例 1:strcpy_s 和 strcat_s
#include <stdio.h>
#include <string.h>int main() {char dest[20]; // 目标缓冲区大小为 20const char *src = "Hello, World!";// 使用 strcpy_s 将 src 复制到 destif (strcpy_s(dest, sizeof(dest), src) != 0) {printf("strcpy_s failed!\n");return 1; // 返回错误代码} else {printf("After strcpy_s: %s\n", dest);}// 使用 strcat_s 将 " C Language" 追加到 destconst char *appendStr = " C Language";if (strcat_s(dest, sizeof(dest), appendStr) != 0) {printf("strcat_s failed!\n");return 1; // 返回错误代码} else {printf("After strcat_s: %s\n", dest);}return 0;
}
输出:
After strcpy_s: Hello, World!
strcat_s failed!
在这个示例中,strcpy_s 成功将字符串复制到目标缓冲区,但由于 dest 缓冲区的大小不足以容纳追加的内容,strcat_s 返回错误并防止溢出。
示例 2:memcpy_s
#include <stdio.h>
#include <string.h>int main() {char src[] = "Sensitive Data";char dest[15]; // 目标缓冲区大小为 15// 使用 memcpy_s 将数据复制到 destif (memcpy_s(dest, sizeof(dest), src, strlen(src) + 1) != 0) {printf("memcpy_s failed!\n");return 1; // 返回错误代码} else {printf("After memcpy_s: %s\n", dest);}return 0;
}
输出:
After memcpy_s: Sensitive Data
memcpy_s 确保 dest 缓冲区足够大,以容纳源字符串的所有数据。如果缓冲区不够,函数会返回错误并防止执行不安全的内存复制。
示例 3:strtok_s
#include <stdio.h>
#include <string.h>int main() {char str[] = "apple,orange,banana";char *token;char *context = NULL;// 使用 strtok_s 分割字符串token = strtok_s(str, ",", &context);while (token != NULL) {printf("Token: %s\n", token);token = strtok_s(NULL, ",", &context);}return 0;
}
输出:
Token: apple
Token: orange
Token: banana
在这个例子中,strtok_s 使用上下文参数来避免多线程环境下的安全问题。每次调用都不会影响其他线程中的字符串分割。
总结
C 语言中的安全函数是为了提高代码的安全性而设计的,尤其是在防止缓冲区溢出、内存越界等常见错误方面提供了有效的防护。通过使用这些函数,您可以确保程序在处理字符串和内
相关文章:
32. C 语言 安全函数( _s 尾缀)
本章目录 前言什么是安全函数?安全函数的特点主要的安全函数1. 字符串操作安全函数2. 格式化输出安全函数3. 内存操作安全函数4. 其他常用安全函数 安全函数实例示例 1:strcpy_s 和 strcat_s示例 2:memcpy_s示例 3:strtok_s 总结 …...
Android T(13) 源码分析 — BufferQueue 的分析
Android T(13) 源码分析 — BufferQueue 的分析 文章目录 Android T(13) 源码分析 — BufferQueue 的分析前言摘要一、Java 层的 BufferQueue 分析二、原生层的 BufferQueue 分析1、BLASTBufferQueue 的创建2、BLASTBufferQueue 的更新3、Surface 的创建 总结 前言 该系列文章…...
Vite+TS项目中配置路径别名
在使用 Vite 和 TypeScript 的项目中配置路径别名,可以简化模块导入路径,提高代码的可读性和维护性。以下是详细的步骤和示例代码: 1. 配置 Vite 别名 前置条件 下载types/node 下面引入的path会用到 npm install types/node --save-dev原…...
看盘细节系列 篇二:集合竞价的9点18分大单打到3%以下或以上,9点19分撤单
文章目录 系列文章现象原因分析时间点含义正常情况测试市场反应诱导跟风操纵股价意图系列文章 看盘细节系列 篇一:集合竞价尾盘突变 现象 集合竞价中 9 点 18 分通过一笔大单或连续几笔大单将股价打到 3% 以下或以上,9 点 19 分又迅速撤单。从而在分时图上留下一根长长的上…...
Java继承简介
继承的本质:是代码的复用,重复使用已经定义好的方法和域(即全局变量) 要掌握继承首先要了解Java方法的重载和重写 方法的重载和重写 方法的重载 当前方法名相同,但是参数类型不同,发生重载 类比数学函…...
redis之哨兵集群搭建
一:哨兵集群工作概览图 1.监控:sentinel通过心跳监控redis的master和slave实例是否正常工作 2.故障转移:假如master出现故障,sentinel会选举一个slave作为新的master,当故障实例恢复后身份会变成slave,会以…...
保姆级AI开发环境搭建
目录 windows下环境搭建1. Python环境搭建2. 下载vLLM2.1 安装CUDA2.2 安装Pytorch2.3 安装vllm 3. 部署Deepseek(huggingface)3.1 DeepSeek的优化建议 4. ollama快速部署Deepseek4.1 下载Ollama4.2 配置Ollma4.2 运行模型4.3 其他Ollama命令 linux下环境…...
Arduino 型号的对比
常见 Arduino 型号的对比表格 涵盖了不同型号的关键参数和特点,方便你根据项目需求进行选择: 型号Arduino UnoArduino Mega 2560Arduino LeonardoArduino NanoArduino Due微控制器ATmega328PATmega2560ATmega32U4ATmega328P 或 ATmega168SAM3X8E&#…...
Kafka系列之:定位topic只能保存最新数据的原因
Kafka系列之:定位topic只能保存最新数据的原因 一、背景二、定位排查方向三、深入排查一、背景 kafka topic保存的数据少,topic只能保存最新的数据二、定位排查方向 能想到的定位排查方向:topic能存储的数据量、topic数据保存的时间、topic数据大小./bin/kafka-configs.sh -…...
AtCoder Beginner Contest 391(A~E题题解)
A - Lucky Direction 思路:纯模拟的一个水题 #include <bits/stdc.h> using namespace std; #define int long long string s; signed main() { cin>>s;for(int i0;i<s.size();i){char cs[i];if(cN){cout<<"S";}else if(c…...
mysql mvcc 锁 关系
多版本并发控制(MVCC)是一种用于数据库并发控制的机制,它可以在保证数据一致性的同时,提高数据库的并发性能。下面结合 MVCC 机制,详细阐述常见的四种事务隔离级别(读未提交、读已提交、可重复读、串行化&a…...
安卓手机基于 Termux 安装 AList 并设置开机自启的详细教程
安装 AList 安装 Termux: 点击下载 更新软件包:打开 Termux,运行以下命令以更新软件包列表并升级已安装的软件包: bash复制 pkg update && pkg upgrade安装 AList:运行以下命令安装 AList: bash复…...
LeetCode:503.下一个更大元素II
跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的! 代码随想录 LeetCode:503.下一个更大元素II 给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[…...
实验5 配置OSPFv2验证
实验5 配置OSPFv2验证 1.实验目的 (1)OSPFv2 验证的类型和意义。 (2)配置基于区域的 OSPFv2 简单口令验证和 MD5 验证的方法。 (3)配置基于链路的 OSPFv2 简单口令验证和 MD5 验证的方法。 2.实验准备 配置…...
第二节 docker基础之---镜像构建及挂载
查看当前镜像: [rootdocker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE [rootdocker ~]#很明显docker是咱们新搭建的所以目前还没有镜像 1,搜索镜像: [rootdocker ~]# docker search centos 搜索镜像并过滤是官…...
论文阅读:MGMAE : Motion Guided Masking for Video Masked Autoencoding
MGMAE:Motion Guided Masking for Video Masked Autoencoding Abstract 掩蔽自编码(Masked Autoencoding)在自监督视频表示学习中展现了出色的表现。时间冗余导致了VideoMAE中高掩蔽比率和定制的掩蔽策略。本文旨在通过引入运动引导掩蔽策略࿰…...
记录一下 在Mac下用pyinstallter 打包 Django项目
安装: pip install pyinstaller 在urls.py from SheepMasterOneToOne import settings from django.conf.urls.static import staticurlpatterns [path("admin/", admin.site.urls),path(generate_report/export/, ReportAdmin(models.Report, admin.site).generat…...
【漫话机器学习系列】084.偏差和方差的权衡(Bias-Variance Tradeoff)
偏差和方差的权衡(Bias-Variance Tradeoff) 1. 引言 在机器学习模型的训练过程中,我们常常面临一个重要的挑战:如何平衡 偏差(Bias) 和 方差(Variance),以提升模型的泛…...
deepseek本地部署-linux
1、官网推荐安装方法(使用脚本,我绕不过github,未采用) 登录ollama下载网站https://ollama.com/download/linux,linux下有下载脚本。 正常来说,在OS系统下直接执行脚本即可。 2、手动安装方法 2.1获取ol…...
解决使用python提取word文档中所有的图片时图片丢失的问题
python解析word文档,提取文档中所有的图片并保存,并将原图位置用占位符替换。 问题描述 利用python-dox库解析word文档,并提取里面的所有图片时发现会出现一摸一样的图片只解析一次,导致图片丢失,数量不对的情况。 …...
Versal AI Engine加速椭圆曲线密码学计算实践
1. 项目概述:Versal AI Engine加速椭圆曲线密码学计算在当今的数字安全领域,椭圆曲线密码学(ECC)因其高安全性和计算效率成为主流方案。其中,多标量乘法(MSM)作为ECC的核心运算,在零…...
Steam成就管理神器:如何在5分钟内解锁所有成就的终极完整指南
Steam成就管理神器:如何在5分钟内解锁所有成就的终极完整指南 【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager 还在为Steam游戏中那些遥不可及的…...
模块二-数据选择与索引——08. 条件筛选
08. 条件筛选 1. 概述 条件筛选是数据分析中最常用的操作之一。通过布尔表达式,可以快速筛选出满足特定条件的数据行,实现数据过滤、异常检测、子集提取等功能。 import pandas as pd import numpy as np# 创建示例数据 np.random.seed(42) df pd.DataF…...
硬件相关项目内容介绍(硬件咱们也有相关技术支持内容哦)
硬件相关项目内容介绍(硬件咱们也有相关技术支持内容哦) 硬件咱们也有相关技术支持内容哦。 主要看大家喜欢什么,硬件内容咱们会不定期更新分享,大家要是喜欢,后续就安排上实物实操。也虚心听取大家建议,不…...
3分钟掌握Word转HTML:Mammoth.js让你的文档转换变得如此简单
3分钟掌握Word转HTML:Mammoth.js让你的文档转换变得如此简单 【免费下载链接】mammoth.js Convert Word documents (.docx files) to HTML 项目地址: https://gitcode.com/gh_mirrors/ma/mammoth.js 在现代办公和内容管理中,Word转HTML的需求无处…...
Python爬虫实战:构建智能职位信息聚合工具JobClaw
1. 项目概述:一个面向开发者的智能职位信息聚合与解析工具最近在帮团队招聘和看机会的朋友聊天,发现一个挺普遍的问题:大家找技术岗位,要么在几个主流招聘App上反复刷,信息分散且格式不一;要么就是盯着几个…...
智能产品系统架构分析 - 智能办公系统架构分层
方向:方案分析、架构设计、模块分解 智能产品系统架构分析:智能办公系统架构分层。 对智能办公系统进行架构分层分析,给出实例、UML建模、项目结构等。 “智能产品系统架构分析:智能办公系统架构分层”。 包含设备控制、预约管…...
ncmdumpGUI终极使用教程:轻松解密网易云音乐NCM文件
ncmdumpGUI终极使用教程:轻松解密网易云音乐NCM文件 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 还在为网易云音乐下载的NCM格式文件无法在普通…...
WarcraftHelper:3步解决魔兽争霸3卡顿与兼容性问题终极指南
WarcraftHelper:3步解决魔兽争霸3卡顿与兼容性问题终极指南 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否还在为魔兽争霸3在现代电…...
构建AI助手持久记忆系统:Rekall项目实践与MCP协议应用
1. 项目概述:为你的AI助手构建一个“第二大脑”如果你和我一样,日常重度依赖 Claude Code、Cursor 这类AI编程助手,那你一定遇到过这个痛点:每次开启一个新的会话,AI助手就像得了“健忘症”,对之前讨论过的…...
