[C/C++內存安全]_[中級]_[安全處理字符串]

場景

  1. 在現代C++開發指南出來后,并不建議使用C的某些內存不安全的字符串處理函數。那么有哪些函數不安全?

說明

  1. 內存安全方面,肯定是要向Rust看齊的。使用標準std::string字符串類,很大情況能避免緩沖區溢出問題。

  2. 如果舊項目里有用到以下的這些C字符串函數,那么最好用std::string改寫吧。

    • strcpy: 不要使用.strcpy,目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。strcpy最后會復制源緩沖區的\0到目標緩沖區末尾,前提是目標緩沖器有足夠的大小。

    • strcat: 不要使用. 只是在目標緩沖區的0位置開始添加新的字符串。目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。strcat最后會復制源緩沖區的\0到目標緩沖區末尾,前提是目標緩沖器有足夠的大小。

    • sprintf: 不要使用. 目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。sprintf最后會復制源緩沖區的\0`到目標緩沖區末尾,前提是目標緩沖器有足夠的大小。

    • strncpy: 不要使用. 目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。·strncpy·最后不會復制一個結束符到目標緩沖區,如果目標緩沖區不是以0結尾,那么在讀取目標緩沖區時也會讀取越界。

    • strncat: 不要使用.strncat 目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。·strncat·最后會復制源緩沖區的\0到目標緩沖區末尾,前提是目標緩沖器有足夠的大小。

  3. strcpy,strcat,strncpystrncat可以使用std::string代替;sprintf可以使用snprintf或者stringstream代替。

例子

  1. 以下例子使用這些危險的C函數處理字符串,并使用std::stringstringstream來替換之。
#include <iostream>
#include <string.h>
#include <string>
#include <iostream>
#include <sstream>
#include <iomanip>using namespace std;void TestUnsafeCStringFunc()
{const int kBufSize = 32;char buf[kBufSize] = {0};string str;// 30個字符const char kStr[] = "http://blog.csdn.net/infoworld";constexpr int kStrSize = sizeof(kStr) - 1;// 1. 不要使用.`strcpy`,目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。//  -- `strcpy`最后會復制源緩沖區的`\0`到目標緩沖區末尾,前提是目標緩沖器有足夠的大小。strcpy(buf, kStr);cout << "strcpy: " << buf << endl;//  -- 使用`string`的代替.str.append(kStr);cout << "string: " << str << endl;// 2. 不要使用.同`strcpy`,只是在目標緩沖區的`0`位置開始添加新的字符串。目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。//  -- `strcat`最后會復制源緩沖區的`\0`到目標緩沖區末尾,前提是目標緩沖器有足夠的大小。memset(buf, 0, sizeof(buf));strcat(buf, kStr);strcat(buf, "/");cout << "strcat: " << buf << endl;//  -- 使用`string`的代替.str.clear();str.append(kStr);str.append("/");cout << "string: " << str << endl;// 3. 不要使用. 目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。//  -- `sprintf`最后會復制源緩沖區的`\0`到目標緩沖區末尾,前提是目標緩沖器有足夠的大小。sprintf(buf, "%d-%.2d-%.2d", 2025, 7, 22);cout << "sprintf: " << buf << endl;// -- 方法1:使用`stringstream`代替stringstream ss;ss << 2025 << "-" << std::setw(2) << std::setfill('0') << 7 << "-"<< std::setw(2) << std::setfill('0') << 22;str = ss.str();cout << "stringstream: " << str << endl;// -- 方法2: 使用`snprintf`代替.// -- 安全,指定目標緩沖區大小,最多指定目標緩沖區大小`-1`個字符被寫入,之后會添加一個結束符。// -- 如果`buf`為`NULL`,并且目標緩沖區大小為`0`時,返回寫源字符串所需要的總大小, 不包括結束符。snprintf(buf,sizeof(buf),"%d-%.2d-%.2d", 2025, 7, 22);cout << "snprintf: " << buf << endl;auto number = snprintf(NULL,0,"%d-%.2d-%.2d", 2025, 7, 22);cout << "snprintf number: " << number << endl;auto myBuf = (char*)malloc(number+1);sprintf(myBuf,"%d-%.2d-%.2d", 2025, 7, 22);cout << "myBuf: " << myBuf << endl;free(myBuf);// 4. 不要使用. `strncpy` 目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。// -- ·strncpy·最后不會復制一個結束符到目標緩沖區,如果目標緩沖區不是以`0`結尾,那么在讀取目標緩沖區時也會讀取越界。memset(buf, 0, sizeof(buf));strncpy(buf, kStr, kStrSize);cout << "strncpy: " << buf << endl;// -- 同上,還是使用`std::string`代替。// 5. 不要使用. `strncat` 目標緩沖區沒有設置最大接收的大小,容易造成緩沖區溢出。// -- ·strncat·最后會復制源緩沖區的`\0`到目標緩沖區末尾,前提是目標緩沖器有足夠的大小。buf[kBufSize - 1] = '1'; // 測試最后添加一個`1`字符,調用`strncat`后會使用`0`把它覆蓋。strncat(buf, "/", 1);cout << "strncat: " << buf << endl;// -- 同上,還是使用`std::string`代替。
}int main()
{std::cout << "Hello World!\n";std::cout << "=========== TestUnsafeCStringFunc =========!\n";TestUnsafeCStringFunc();
}

輸出

Hello World!
=========== TestUnsafeCStringFunc =========!
strcpy: http://blog.csdn.net/infoworld
string: http://blog.csdn.net/infoworld
strcat: http://blog.csdn.net/infoworld/
string: http://blog.csdn.net/infoworld/
sprintf: 2025-07-22
stringstream: 2025-07-22
snprintf: 2025-07-22
snprintf number: 10
myBuf: 2025-07-22
strncpy: http://blog.csdn.net/infoworld
strncat: http://blog.csdn.net/infoworld/

參考

  1. strcpy

  2. strcat

  3. strncpy

  4. strncat

  5. sprintf,snprintf

  6. stringstream

  7. string

  8. C++11語言特性和標準庫

  9. 如何實現std::string自己的Format(sprintf)函數

  10. 避免使用wsprintf函數

  11. setw

  12. setfill

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

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

相關文章

【CNN】卷積神經網絡- part1

1.卷積1.局部連接定義&#xff1a;只是于輸入數據的一部分區域相連&#xff0c;每個神經元只關注一小部分作用&#xff1a;模仿人類的視野機制&#xff0c;極大的減少了模型參數的數量&#xff0c;降低了計算成本2.權重共享定義&#xff1a;所有神經元使用相同的權重向量來檢測…

漏洞生命周期管理:從發現到防護的全流程方案

漏洞并非孤立存在&#xff0c;而是遵循 “發現→評估→修復→驗證→閉環” 的生命周期。多數企業安全事件的根源并非缺乏漏洞發現能力&#xff0c;而是對漏洞生命周期的管理缺失 —— 大量漏洞被發現后長期未修復&#xff0c;或修復后未驗證效果。構建全流程漏洞生命周期管理體…

opencv圖像基本操作解析與實操

圖片操作cv2.namedWindow() 創建命名窗口cv2.imshow()顯示窗口cv2.destroyAllwindws()摧毀窗口cv2.resizeWindow()改變窗口大小cv2.waitKey()等待用戶輸入cv2.imread()讀取圖像img.shape 圖片h、w、c&#xff08;高、寬、通道數import cv2 # opencv讀取的格式是BGR import m…

kafka--基礎知識點--6.1--LEO、HW、LW

在 Apache Kafka 中&#xff0c;LEO&#xff08;Log End Offset&#xff09;、HW&#xff08;High Watermark&#xff09;、和 LW&#xff08;Low Watermark&#xff09; 是副本機制和日志管理中的核心概念&#xff0c;共同確保數據一致性、可見性和存儲效率。以下是它們的詳細…

在線深凹槽深檢測方法都有哪些 —— 激光頻率梳 3D 輪廓檢測

引言在制造業中&#xff0c;深凹槽深度的精確檢測是保證零部件質量的關鍵環節。隨著智能制造的推進&#xff0c;在線檢測需求日益迫切&#xff0c;傳統檢測方法在效率和精度上的不足逐漸顯現。本文將梳理在線深凹槽深的傳統檢測方法&#xff0c;并重點探討激光頻率梳 3D 輪廓檢…

NumPy 數組拼接的高級技巧與實踐

在數據處理和機器學習領域&#xff0c;NumPy 是 Python 中最核心的科學計算庫之一。NumPy 數組&#xff08;ndarray&#xff09;的拼接操作是數據預處理中極為常見的需求。本文將深入探討如何將不同形狀的 NumPy 數組進行拼接&#xff0c;特別是如何將多個一維數組與二維數組進…

原創-基于 PHP 和 MySQL 的證書管理系統 第三版

第一版屬于開源版本&#xff0c;所以后臺功能沒有開發許多出來&#xff0c;今天分享證書查詢第三版&#xff1b; 通過幾天的緊急寫代碼及測試&#xff1b;第三版基本可以上線上&#xff0c;不過后面有一些BUG只能一邊修復。 演示地址&#xff1a;物星科云證書管理系統 第三版…

爬蟲虛擬環境

conda create --name myrepenv python3.12創建一個名為 myrepenv、Python 版本為 3.12 的全新 Conda 虛擬環境&#xff0c;適合需要隔離依賴或測試不同 Python 版本的項目。我的方式創建(需要指定盤符)conda create --prefixD:\Anaconda3\envs\myrepenv python3.12展示所下的co…

Netty集群方案詳解與實戰(Zookeeper + Redis + RabbitMQ)

一、背景 二、Netty 單體架構的優缺點 優點 缺點 三、Netty 集群架構的優缺點 優點 缺點 四、適用場景對比 五、Netty單體架構代碼實現 六、Netty集群架構方案實現 方案一、Nginx負載均衡實現集群(較為簡單) Nginx配置 前端連接方式 方案二、NacosGateway&#xff08;結合…

Oracle遷移到高斯,查詢字段默認小寫,解決辦法

一、問題說明 Oracle中&#xff0c;查詢結果字段默認大寫。高斯中&#xff0c;查詢結果字段默認小寫。在Mybatis的xml中&#xff0c;如果查詢語句使用Map接收查詢結果&#xff0c;使用resultType"java.util.HashMap"或resultType"Map"等寫法&#xff0c;返…

Android Jetpack Compose + MVVM 開發流程深度分析

核心組件關系圖 [View] -- 觀察 --> [ViewModel] -- 操作 --> [Repository]| | Compose UI StateFlow/LiveData| | 用戶交互事件 Room/Retrofit| …

Tailwind CSS快速上手 Tailwind CSS的安裝、配置、使用

&#x1f4da;前言 在Web前端開發的歷史長河中&#xff0c;CSS的編寫方式經歷了多次演進&#xff0c;從早期的原生CSS 到 CSS預處理(Less/Sass/Stylus) 到 CSS-in-JS(Styled-Components/Emotion) 再到 Utility-First 原子化CSS。每一種演進方案其本質都是圍繞“開發效率”、“…

單例模式的智慧:從UVM看控制的藝術

有時候&#xff0c;生活中的很多東西其實只需要一個就夠了&#xff0c;就像一個公司只需要一個CEO&#xff0c;一個王朝只需要一個皇帝。在UVM驗證環境中&#xff0c;也有很多這樣的需求——有些對象&#xff0c;我們希望它在整個仿真過程中只存在一個實例。這就是我們今天要聊…

Hexo - 免費搭建個人博客01 - 安裝軟件工具

導言我的博客&#xff1a;https://q164129345.github.io/ Hexo 作為一個 Node.js 框架&#xff0c;它依賴于 Node.js 運行時環境來執行。 一、安裝Node.js官方網址&#xff1a;https://nodejs.org/zh-cn追求系統穩定性、可靠性以及希望減少維護頻率的用戶來說&#xff0c;LTS版…

【Kubernetes】集群啟動nginx,觀察端口映射,work節點使用kubectl配置

參考b站叩丁狼總結&#xff1a;完整版Kubernetes&#xff08;K8S&#xff09;全套入門微服務實戰項目&#xff0c;帶你一站式深入掌握K8S核心能力 在master節點執行 kubectl create deployment nginx --imagenginxkubectl expose deployment nginx --port80 --typeNodePort1. …

20250704-基于強化學習在云計算環境中的虛擬機資源調度研究

基于強化學習在云計算環境中的虛擬機資源調度研究 隨著云計算規模的持續擴大&#xff0c;數據中心虛擬機資源調度面臨動態負載、異構資源適配及多目標優化等挑戰。傳統啟發式算法在復雜場景下易陷入局部最優&#xff0c;而深度強化學習&#xff08;DRL&#xff09;憑借序貫決策…

day 33打卡

day 21 常見的降維算法 # 先運行之前預處理好的代碼 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import warnings warnings.filterwarnings(ignore)# 設置中文字體 plt.rcParams[font.sans-serif] [SimHei] plt.rcParam…

sec(x)積分推導

在MATLAB中繪制 sec?(x)、cos(x) 和 ln?∣sec?(x)tan?(x)∣的函數圖像&#xff0c;需要特別注意 sec?(x) 在 cos?(x)0&#xff08;即 xπ/2kπ&#xff09;處的奇點。&#xff08;deepseek生成代碼&#xff09;% 定義x范圍&#xff08;-2π到2π&#xff09;&#xff0c;…

gpt面試題

vue面試題 &#x1f4a1; 一、響應式系統相關 ?1. Vue 3 的響應式系統是如何實現的&#xff1f;和 Vue 2 有何本質區別&#xff1f; 答案&#xff1a; Vue 3 使用 Proxy 實現響應式&#xff08;位于 vue/reactivity 模塊&#xff09;&#xff0c;替代 Vue 2 的 Object.defineP…

【基于OpenCV的圖像處理】圖像預處理之圖像色彩空間轉換以及圖像灰度化處理

目錄 零、寫在前面的話 一、圖像色彩空間轉換 1.1 RGB顏色空間 1.1.1 RGB顏色空間概念 1.1.2 RGB顏色模型?編輯 1.1.3 關于顏色加法 1.1.4 顏色加權加法 1.2 HSV顏色空間 1.2.1 HSV顏色空間概念 1.2.2 HSV顏色模型 1.2.3 應用意義 1.3 顏色轉換 1.3.1 轉換方法 …