c - Linux 中的 kmemdup_nul() 和 kstrndup() 有什么区别?
问题描述
它们是相似的功能,但它们之间的确切区别是什么?Linux 文档指出:
注意:如果确切知道大小,请改用 kmemdup_nul()。
解决方案
这两个函数都通过分配所需的内存kmalloc()
,然后NUL
在分配的缓冲区的末尾放置一个终止符。两者之间的唯一区别是kstrndup()
首先调用strnlen()
计算字符串的长度以及所需的大小,从而扫描字符串。
您可以将kmemdup_nul()
其视为kstrndup()
. 如果您已经知道字符串的长度,则可以避免初始扫描,只需kmemdup_nul()
将长度作为参数传入即可。这可以节省时间,因为不需要扫描字符串,这就是您看到该注释的原因。
此外,kstrndup()
如果字符串比 短,则可以节省空间max
,因此,如果您不知道字符串的长度,即使kmemdup_nul()
可以正常工作,您也可能需要调用kstrndup()
以潜在地节省空间。
您可以从代码中清楚地看到,这两个函数之间的唯一区别是对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] = '\0';
}
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] = '\0';
}
return buf;
}
EXPORT_SYMBOL(kmemdup_nul);
推荐阅读
- php - PHP - 获取当前 UTC 日期时间的正确方法
- r - 用预先选择的颜色分别为 ggplot 中的每个数据点在方框和晶须图中着色
- javascript - XMLHttpRequest 服务器响应状态为 405(不允许方法)
- javascript - react-table 'pivotBy' :如何在 pivotBy 中使用的列上进行过滤
- gradle - 模块不在 Gradle 视图中
- git - git - 推送时在仓库中保留特定文件
- android - 如何从 Android App Incoming Intent 获取 URI
- c - 在哪里可以找到 Apache 用于处理 .htaccess 的源代码?
- python-3.x - 从单词列表中查找给定句子的字谜
- apache - 子文件夹 .htacess 不覆盖父 .htacess 选项