#include <iostream>
using namespace std;
struct Packet {
int a;
char b[17];
int c;
};
// char* dest has form char dest[n], src has length <= n and is null-terminated
// After the function, dest should satisfy:
// - If strlen(src)==n, dest is not null terminated
// - If strlen(src) < n, dest[n-1] = dest[strlen(src)] = '\0'
static void strncpy_faster(char* dest, const char* src, size_t n) {
size_t i;
for (i = 0; i < n; i ) {
dest[i] = src[i];
if (src[i] == '\0')
break;
}
//while (i < n) {dest[i] = '\0'; i ;} // C standard strncpy do this
if (i < n)
dest[n - 1] = '\0';
}
string charArrayToString(const char* a, size_t n) {
size_t len = 0;
while (len < n && a[len]!='\0') len ;
return std::string(a, a len);
}
int main()
{
string s = "12341234123412345";
Packet packet;
strncpy_faster(packet.b, s.c_str(), 17);
cout << charArrayToString(packet.b, sizeof(packet.b)) << "\n";
s = "12345";
strncpy_faster(packet.b, s.c_str(), 17);
cout << charArrayToString(packet.b, sizeof(packet.b));
return 0;
}
我正在處理具有固定大小字符陣列的結構。假設我真的,真的想保持結構體的大小很小(或者我需要通過網路發送它們),所以std::string我的結構體中沒有使用它(它花費 32 位元組,而我有多個大小為 4-20 的小字符陣列)。我對 strncpy 有兩個問題:
strncpy具有相同長度的 2 個字符陣列將發出關于“可能沒有以空字符結尾的字符”的警告,這是有意的,但我不需要那個警告。strncpydest[strlen(src) -> n-1]用'\0'.填充所有剩余的字符(來自)。這在我的程式中是一種處理的浪費。
所以,我strncpy_faster最多只為 '\0' 分配 2 個位置:陣列的最后一個元素,以及strlen(src). 由于std::string()需要以空字符結尾的字符陣列 (NTCA),因此我使用charArrayToString()將非 NTCA 轉換為字串。
這個版本strncpy安全嗎?是否有任何 C/C 函式需要strncpy用 填充所有剩余位元組'\0',或者它們是否只需要一個空終止符?我不知道為什么標準要求strncpy將剩余位元組清零。
uj5u.com熱心網友回復:
這個版本的 strncpy 安全嗎?
是的。
它是安全strncpy的。所以……不安全。
是否有任何 C/C 函式需要 strncpy 用 '\0' 填充所有剩余位元組,或者它們是否只需要一個空終止符?
沒有任何功能需要它。
來自 Linux 手冊頁的注釋man strcpy:
筆記
一些程式員認為 strncpy() 效率低下且容易出錯。如果程式員知道(即包含要測驗的代碼!)dest 的大小大于 src 的長度,則可以使用 strcpy()。
strncpy() 的一個有效(和預期)用途是將 C 字串復制到固定長度的緩沖區,同時確保緩沖區不會溢位并且目標緩沖區中未使用的位元組被清零(可能是為了防止資訊泄漏,如果緩沖區將被寫入媒體或通過行程間通信技術傳輸到另一個行程)。
考慮使用(和/或實施)strlcpy。記住優化的第一條規則。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/402513.html
標籤:
