kmemdup_nul() 和 Linux 中的 kstrndup() 有什么区别?
What is the difference between kmemdup_nul() and kstrndup() in Linux?
它们是相似的功能,但它们之间的确切区别是什么? Linux 文档指出:
Note: Use kmemdup_nul() instead if the size is known exactly.
这两个函数都通过kmalloc()
分配所需的内存,然后在分配的缓冲区末尾放置一个NUL
终止符。两者之间唯一的区别是 kstrndup()
首先调用 strnlen()
来计算字符串的长度,从而计算出所需的大小,从而扫描字符串。
您可以将 kmemdup_nul()
视为 kstrndup()
的优化版本。如果您已经知道字符串的长度,则可以避免初始扫描,只需使用 kmemdup_nul()
将长度作为参数传递。这样可以节省时间,因为不需要扫描字符串,这也是您看到该注释的原因。
此外,如果字符串比max
短,kstrndup()
会保存space,所以如果你不知道字符串的长度,即使kmemdup_nul()
也可以,您可能想调用 kstrndup()
来潜在地保存 space.
从代码中可以清楚的看出,这两个函数唯一的区别就是对strnlen()
的调用。这是源代码,来自 mm/util.c
:
/**
* kstrndup - allocate space for and copy an existing string
* @s: the string to duplicate
* @max: read at most @max chars from @s
* @gfp: the GFP mask used in the kmalloc() call when allocating memory
*
* Note: Use kmemdup_nul() instead if the size is known exactly.
*
* Return: newly allocated copy of @s or %NULL in case of error
*/
char *kstrndup(const char *s, size_t max, gfp_t gfp)
{
size_t len;
char *buf;
if (!s)
return NULL;
len = strnlen(s, max);
buf = kmalloc_track_caller(len+1, gfp);
if (buf) {
memcpy(buf, s, len);
buf[len] = '[=10=]';
}
return buf;
}
EXPORT_SYMBOL(kstrndup);
/**
* kmemdup_nul - Create a NUL-terminated string from unterminated data
* @s: The data to stringify
* @len: The size of the data
* @gfp: the GFP mask used in the kmalloc() call when allocating memory
*
* Return: newly allocated copy of @s with NUL-termination or %NULL in
* case of error
*/
char *kmemdup_nul(const char *s, size_t len, gfp_t gfp)
{
char *buf;
if (!s)
return NULL;
buf = kmalloc_track_caller(len + 1, gfp);
if (buf) {
memcpy(buf, s, len);
buf[len] = '[=10=]';
}
return buf;
}
EXPORT_SYMBOL(kmemdup_nul);
它们是相似的功能,但它们之间的确切区别是什么? Linux 文档指出:
Note: Use kmemdup_nul() instead if the size is known exactly.
这两个函数都通过kmalloc()
分配所需的内存,然后在分配的缓冲区末尾放置一个NUL
终止符。两者之间唯一的区别是 kstrndup()
首先调用 strnlen()
来计算字符串的长度,从而计算出所需的大小,从而扫描字符串。
您可以将 kmemdup_nul()
视为 kstrndup()
的优化版本。如果您已经知道字符串的长度,则可以避免初始扫描,只需使用 kmemdup_nul()
将长度作为参数传递。这样可以节省时间,因为不需要扫描字符串,这也是您看到该注释的原因。
此外,如果字符串比max
短,kstrndup()
会保存space,所以如果你不知道字符串的长度,即使kmemdup_nul()
也可以,您可能想调用 kstrndup()
来潜在地保存 space.
从代码中可以清楚的看出,这两个函数唯一的区别就是对strnlen()
的调用。这是源代码,来自 mm/util.c
:
/**
* kstrndup - allocate space for and copy an existing string
* @s: the string to duplicate
* @max: read at most @max chars from @s
* @gfp: the GFP mask used in the kmalloc() call when allocating memory
*
* Note: Use kmemdup_nul() instead if the size is known exactly.
*
* Return: newly allocated copy of @s or %NULL in case of error
*/
char *kstrndup(const char *s, size_t max, gfp_t gfp)
{
size_t len;
char *buf;
if (!s)
return NULL;
len = strnlen(s, max);
buf = kmalloc_track_caller(len+1, gfp);
if (buf) {
memcpy(buf, s, len);
buf[len] = '[=10=]';
}
return buf;
}
EXPORT_SYMBOL(kstrndup);
/**
* kmemdup_nul - Create a NUL-terminated string from unterminated data
* @s: The data to stringify
* @len: The size of the data
* @gfp: the GFP mask used in the kmalloc() call when allocating memory
*
* Return: newly allocated copy of @s with NUL-termination or %NULL in
* case of error
*/
char *kmemdup_nul(const char *s, size_t len, gfp_t gfp)
{
char *buf;
if (!s)
return NULL;
buf = kmalloc_track_caller(len + 1, gfp);
if (buf) {
memcpy(buf, s, len);
buf[len] = '[=10=]';
}
return buf;
}
EXPORT_SYMBOL(kmemdup_nul);