C++ 自定义编写的 strncpy 没有将所有字符填充为 null 是否安全?
C++ custom-written strncpy without padding all characters to null is it safe?
#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)] = '[=10=]'
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] == '[=10=]')
break;
}
//while (i < n) {dest[i] = '[=10=]'; i++;} // C standard strncpy do this
if (i < n)
dest[n - 1] = '[=10=]';
}
string charArrayToString(const char* a, size_t n) {
size_t len = 0;
while (len < n && a[len]!='[=10=]') 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;
}
我正在处理具有固定大小 char 数组的结构。假设我真的非常想保持结构的大小(或者我需要通过网络发送它们),所以 std::string
没有在我的结构中使用(它花费 32 个字节,而我有多个大小为4-20).我有 2 个关于 strncpy 的问题:
strncpy
具有相同长度的 2 个字符数组将发出关于“可能没有空终止字符”的警告,这是有意的,但我不需要那个警告。
strncpy
用 '[=15=]'
填充所有剩余字符(来自 dest[strlen(src) -> n-1]
)。这在我的程序中是一种浪费。
所以,我的strncpy_faster
最多只给'\0'分配了2个位置:数组的最后一个元素,以及strlen(src)
的位置。由于 std::string()
需要一个以 null 结尾的字符数组 (NTCA),我使用 charArrayToString()
将非 NTCA 转换为字符串。
strncpy
这个版本安全吗?是否有任何 C/C++ 函数需要 strncpy
用 '[=15=]'
填充所有剩余字节,或者它们只需要一个空终止符?我不知道为什么标准要求 strncpy
将剩余字节清零。
Is this version of strncpy safe?
是的。
它和 strncpy
一样安全。所以....不安全。
Are there any C/C++ functions that requires strncpy to fill all leftover bytes with '[=14=]', or do they only need a null terminator?
没有函数需要它。
来自 Linux 手册页的注释 man strcpy
:
NOTES
Some programmers consider strncpy() to be inefficient and error
prone. If the programmer knows (i.e., includes code to test!) that
the size of dest is greater than the length of src, then strcpy() can
be used.
One valid (and intended) use of strncpy() is to copy a C string to
a fixed-length buffer while ensuring both that the buffer is not
overflowed and that unused bytes in the destination buffer are zeroed
out (perhaps to prevent information leaks if the buffer is to be
written to media or transmitted to another process via an interprocess
communication technique).
考虑使用(and/or 实施)strlcpy
。记得关于 first rule of optimization.
#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)] = '[=10=]'
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] == '[=10=]')
break;
}
//while (i < n) {dest[i] = '[=10=]'; i++;} // C standard strncpy do this
if (i < n)
dest[n - 1] = '[=10=]';
}
string charArrayToString(const char* a, size_t n) {
size_t len = 0;
while (len < n && a[len]!='[=10=]') 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;
}
我正在处理具有固定大小 char 数组的结构。假设我真的非常想保持结构的大小(或者我需要通过网络发送它们),所以 std::string
没有在我的结构中使用(它花费 32 个字节,而我有多个大小为4-20).我有 2 个关于 strncpy 的问题:
strncpy
具有相同长度的 2 个字符数组将发出关于“可能没有空终止字符”的警告,这是有意的,但我不需要那个警告。strncpy
用'[=15=]'
填充所有剩余字符(来自dest[strlen(src) -> n-1]
)。这在我的程序中是一种浪费。
所以,我的strncpy_faster
最多只给'\0'分配了2个位置:数组的最后一个元素,以及strlen(src)
的位置。由于 std::string()
需要一个以 null 结尾的字符数组 (NTCA),我使用 charArrayToString()
将非 NTCA 转换为字符串。
strncpy
这个版本安全吗?是否有任何 C/C++ 函数需要 strncpy
用 '[=15=]'
填充所有剩余字节,或者它们只需要一个空终止符?我不知道为什么标准要求 strncpy
将剩余字节清零。
Is this version of strncpy safe?
是的。
它和 strncpy
一样安全。所以....不安全。
Are there any C/C++ functions that requires strncpy to fill all leftover bytes with '[=14=]', or do they only need a null terminator?
没有函数需要它。
来自 Linux 手册页的注释 man strcpy
:
NOTES
Some programmers consider strncpy() to be inefficient and error prone. If the programmer knows (i.e., includes code to test!) that the size of dest is greater than the length of src, then strcpy() can be used.
One valid (and intended) use of strncpy() is to copy a C string to a fixed-length buffer while ensuring both that the buffer is not overflowed and that unused bytes in the destination buffer are zeroed out (perhaps to prevent information leaks if the buffer is to be written to media or transmitted to another process via an interprocess communication technique).
考虑使用(and/or 实施)strlcpy
。记得关于 first rule of optimization.