[英]How to convert current strcpy to strcpy_s?
我有大型項目, strcpy
到處使用。 我想使用strcpy_s
而不是strcpy
。 我想我用了幾乎10,000次strcpy
。 改變每一個strcpy
是如此麻煩。 有沒有有效的轉換方式?
你真的不應該在沒有檢查的情況下這樣做,因為如果沒有智能地完成緩沖管理,那么它就會丟失。
由於目標緩沖區的性質(例如靜態或堆分配)對於strcpy_s()
的正確參數非常重要,並且當然在現有的strcpy()
調用中不存在該信息,因此必須添加它以任何方式。 這需要一個人。
通常像strcpy(dest, src);
這樣的strcpy(dest, src);
可以轉換為strcpy_s(dest, sizeof dest, src);
,但如果dest
是堆分配的,那么這只是指針的大小而不是指向的緩沖區,當然這是錯誤的。
鑒於您已經提供了一個無法推斷出的額外參數( size_t destsz
),這些參數需要准確地從變更中獲益才能獲得真正的問題。
使用strcpy()
10,000次的應用程序聽起來很瘋狂,但你就是你的所在。
首先如果您的時間/資源有限,那么我所能建議的只是一點風險評估。 哪些調用正在復制外部數據(來自文件,操作系統,用戶,端口或套接字等)。 專注於確保那些不會覆蓋,你將更有效地降低風險。
第二,如果您有任何標准變量名稱和標准“最大尺寸”,您可以進行一些全局搜索和替換。
假如您在平台上使用filename
很多並且文件名最多為255個字符(加上NUL),則可以替換strcpy(filename,
with(say) strcpy_s(filename,FILENAME_MAX_SZ
。
如果代碼是“遍布整個地方”,那么你就會有很多工作要做。
替換strcpy(v,
使用strcpy_s(v,SIZE_MAX
(使用正則表達式))是一個表面的躲避,除了可能潛入你的組織代碼質量腳本之外,它實際上並沒有獲得任何東西。我沒有告訴你這樣做!;)
第三,如果您想在C11 _Generic
的世界中漫步,您可以嘗試以下方法:
#define __STDC_WANT_LIB_EXT1__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int strcpy_s(char *dest,size_t destsz,const char *src){
if(strlen(src)>=destsz){
return 1;
}
strcpy(dest,src);
return 0;
}
char *d_strcpy(char *dest,const char *src){
#ifndef NDEBUG
fprintf(stdout,"unsafe copy of %s\n",src);
#endif
return strcpy(dest,src);
}
#define strcpy(dest,src) _Generic (dest,\
char[100] : strcpy_s(dest,sizeof dest,src),\
char*: d_strcpy(dest,src)\
)
int main(void) {
char a[100]={'A','B','\0'};
char *b=malloc(10*sizeof(char));
strcpy(a,"XXX");
strcpy(b,"XYX");
printf("%s %s\n",a,b);
free(b);
return 0;
}
不幸的是,您確實需要指定數組大小,因此需要使用有限的“最大大小”列表,雖然這應該適用於Clang(未經測試)但它在GCC上失敗,因為他們不同意如何解析控制類型! 參見文件:N1930(控制_Generic的表達式)
快樂狩獵。
為什么要替換strcpy()函數? strcpy沒有錯 。 教條地將其更改為strcpy_s
將無法解決任何問題。 您需要做的是考慮每個案例:
這不是strcpy
甚至是字符串所特有的東西,而是代碼中每個數組都必須考慮的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.