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 類型的錯誤碼,以便調用者能夠檢測是否成功執行。

安全函數的特點

  1. 緩沖區大小檢查:安全函數需要明確傳遞目標緩沖區的大小,確保不會發生溢出。
  2. 返回值檢查:大多數安全函數返回一個錯誤代碼,可以通過檢查返回值來判斷是否成功執行。
  3. 錯誤處理:當緩沖區大小不足或者其他錯誤發生時,安全函數會嘗試清空或初始化輸出緩沖區,避免未定義的行為。

主要的安全函數

以下是 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_sstrcat_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 語言中的安全函數是為了提高代碼的安全性而設計的,尤其是在防止緩沖區溢出、內存越界等常見錯誤方面提供了有效的防護。通過使用這些函數,您可以確保程序在處理字符串和內


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67551.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67551.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67551.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

淺談網絡 | 容器網絡之Flannel

目錄 云原生網絡架構深度解構&#xff1a;Flannel的設計哲學與實現機制Flannel架構解析&#xff1a;三層核心設計原則UDP模式&#xff08;用戶態隧道&#xff09;VXLAN模式&#xff08;內核態隧道&#xff09;Host-GW模式&#xff08;直連路由&#xff09; 生產環境架構選型與調…

autosar bsw 的關鍵模塊

AUTOSAR&#xff08;AUTomotive Open System ARchitecture&#xff09;的**基礎軟件層&#xff08;BSW&#xff0c;Basic Software&#xff09;**是汽車電子系統標準化的核心&#xff0c;負責提供硬件抽象、通信、診斷、安全等基礎服務。以下是BSW的關鍵模塊及其功能分類&#…

hive:基本數據類型,關于表和列語法

基本數據類型 Hive 的數據類型分為基本數據類型和復雜數據類型 加粗的是常用數據類型 BOOLEAN出現ture和false外的其他值會變成NULL值 沒有number,decimal類似number 如果輸入的數據不符合數據類型, 映射時會變成NULL, 但是數據本身并沒有被修改 創建表 創建表的本質其實就是在…

2025創業思路和方向有哪些?

創業思路和方向是決定創業成功與否的關鍵因素。以下是一些基于找到的參考內容的創業思路和方向&#xff0c;旨在激發創業靈感&#xff1a; 一、技術創新與融合&#xff1a; 1、智能手機與云電視結合&#xff1a;開發集成智能手機功能的云電視&#xff0c;提供通訊、娛樂一體化體…

航空客戶價值的數據挖掘與分析(numpy+pandas+matplotlib+scikit-learn)

航空客戶價值的數據挖掘與分析(numpy+pandas+matplotlib+scikit-learn) K-Means聚類:https://en.wikipedia.org/wiki/K-means_clustering寫在前面 實現目的:基于K-Means聚類分析模型實現航空客戶價值大數據分析。 電腦系統:Windows 使用軟件:Anaconda(Jupyter Notebook)…

Three.js實戰項目02:vue3+three.js實現汽車展廳項目

文章目錄 實戰項目02項目預覽項目創建初始化項目模型加載與展廳燈光加載汽車模型設置燈光材質設置完整項目下載實戰項目02 項目預覽 完整項目效果: 項目創建 創建項目: pnpm create vue安裝包: pnpm add three@0.153.0 pnpm add gsap初始化項目 修改App.js代碼&#x…

年化19.3%策略集|ctpbee_api替換成openctp整合backtrader實盤方案(代碼+數據)

原創內容第782篇&#xff0c;專注量化投資、個人成長與財富自由。 昨天我們把backtraderctpbee的實盤整合代碼跑通了&#xff0c;年化19.3%&#xff0c;回撤僅8%的實盤策略&#xff0c;以及backtrader整合CTPBee做實盤&#xff08;附python代碼和數據&#xff09; 這兩周我們加…

Android Studio 正式版 10 周年回顧,承載 Androider 的崢嶸十年

Android Studio 1.0 宣發于 2014 年 12 月&#xff0c;而現在時間來到 2025 &#xff0c;不知不覺間 Android Studio 已經陪伴 Androider 走過十年歷程。 Android Studio 10 周年&#xff0c;也代表著了我的職業生涯也超十年&#xff0c;現在回想起來依然覺得「唏噓」&#xff…

OpenEuler學習筆記(十四):在OpenEuler上搭建.NET運行環境

一、在OpenEuler上搭建.NET運行環境 基于包管理器安裝 添加Microsoft軟件源&#xff1a;運行命令sudo rpm -Uvh https://packages.microsoft.com/config/centos/8/packages-microsoft-prod.rpm&#xff0c;將Microsoft軟件源添加到系統中&#xff0c;以便后續能夠從該源安裝.…

詳解python的修飾符

Python 中的修飾符&#xff08;Decorator&#xff09;是一種用于修改或擴展函數或類行為的工具。它們本質上是一個函數&#xff0c;接受另一個函數或類作為參數&#xff0c;并返回一個新的函數或類。修飾符通常用于在不修改原函數或類代碼的情況下&#xff0c;添加額外的功能。…

低代碼產品插件功能一覽

下圖是統計的目前市面上流行的低代碼、零代碼產品的插件功能。 產品名稱 產品類型 官方插件數量 支持拓展 官方插件功能 宜搭 零代碼 3 暫不支持 云打印、CAD看圖、打印表單詳情 微搭 低代碼 1 暫不支持 小程序 明道云 低代碼 2 支持 視圖、工作流節點 簡道…

Vscode編輯器下 Markdown無法顯示圖片

1.問題 在vscode 編輯器中無法預覽 markdon 文件中的圖片 2.解決方案 大部分出現這種情況是因為新版本的vscode會阻攔有風險的資源顯示&#xff0c;將安全等級調低即可。 方式一&#xff1a; 1.打開任意 MD 文件&#xff0c;ctrl&#xff0c;調出設置 2. 輸入 markdown.ch…

前端axios攔截器

1. 在main.js導入axios 2. 通過axios對象定義攔截器 import {createApp} from vue import App from ./App.vue import Antd from ant-design-vue; import ant-design-vue/dist/antd.css; import axios from "axios"; import router from ./router import store from …

php-phar打包避坑指南2025

有很多php腳本工具都是打包成phar形式&#xff0c;使用起來就很方便&#xff0c;那么如何自己做一個呢&#xff1f;也找了很多文檔&#xff0c;也遇到很多坑&#xff0c;這里就來總結一下 phar安裝 現在直接裝yum php-cli包就有phar文件&#xff0c;很方便 可通過phar help查看…

自動化運維的未來:從腳本到AIOps的演進

點擊進入IT管理資料庫 一、自動化運維的起源&#xff1a;腳本時代 &#xff08;一&#xff09;腳本在運維中的應用場景 在自動化運維的發展歷程中&#xff0c;腳本扮演著至關重要的角色&#xff0c;它作為最初的操作入口&#xff0c;廣泛應用于諸多日常運維工作場景里。 在系統…

【2024年華為OD機試】(B卷,100分)- 熱點網站統計(Java JS PythonC/C++)

一、問題描述 題目描述 企業路由器的統計頁面需要動態統計公司訪問最多的網頁URL的Top N。設計一個算法&#xff0c;能夠高效動態統計Top N的頁面。 輸入描述 每一行都是一個URL或一個數字&#xff1a; 如果是URL&#xff0c;代表一段時間內的網頁訪問。如果是數字N&#…

《DeepSeek 網頁/API 性能異常(DeepSeek Web/API Degraded Performance):網絡安全日志》

DeepSeek 網頁/API 性能異常&#xff08;DeepSeek Web/API Degraded Performance&#xff09;訂閱 已識別 - 已識別問題&#xff0c;并且正在實施修復。 1月 29&#xff0c; 2025 - 20&#xff1a;57 CST 更新 - 我們將繼續監控任何其他問題。 1月 28&#xff0c; 2025 - 22&am…

基于微信小程序的輔助教學系統的設計與實現

標題:基于微信小程序的輔助教學系統的設計與實現 內容:1.摘要 摘要&#xff1a;隨著移動互聯網的普及和微信小程序的興起&#xff0c;基于微信小程序的輔助教學系統成為了教育領域的一個新的研究熱點。本文旨在設計和實現一個基于微信小程序的輔助教學系統&#xff0c;以提高教…

智能汽車網絡安全威脅報告

近年來隨著智能汽車技術的快速發展&#xff0c;針對智能汽車的攻擊也逐漸從傳統的針對單一車輛控制器的攻擊轉變為針對整車智能化服務的攻擊&#xff0c;包括但不限于對遠程控制應用程序的操控、云服務的滲透、智能座艙系統的破解以及對第三方應用和智能服務的攻擊。隨著WP.29 …

docker中運行的MySQL怎么修改密碼

1&#xff0c;進入MySQL容器 docker exec -it 容器名 bash 我運行了 docker ps命令查看。正在運行的容器名稱。可以看到MySQL的我起名為db docker exec -it db bash 這樣就成功的進入到容器中了。 2&#xff0c;登錄MySQL中 mysql -u 用戶名 -p 回車 密碼 mysql -u root -p roo…