kstrndup函数功能描述:kstrndup( )函数的功能与函数kstrdup( )的功能类似,都是为常量字符串s分配内存空间并将该字符串拷贝到所分配的地址空间中,差别在于kstrudup( )函数多了一个参数len,其含义是拷贝s中最多len字节的内容。
kstrndup文件包含
#include<linux/string.h>
kstrndup函数定义
在内核源码中的位置:linux-3.19.3/mm/util.c
函数定义格式:
char *kstrndup(const char *s, size_t len, gfp_t gfp)
kstrndup输入参数说明
s
:待分配内存空间的字符串。len
:其大小限制了要拷贝的字符串为s的前len字节。gfp
:分配模式,其取值及含义参考kmalloc( )函数的分析。
kstrndup返回参数说明
返回值指向为字符串所分配的内存空间的起始地址。
kstrndup实例解析
编写测试文件:kstrndup.c
头文件及全局变量声明如下:
#include <linux/string.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int __init kstrndup_init(void);
static void __exit kstrndup_exit(void);
模块初始化函数:
int __init kstrndup_init(void)
{
char * temp;
const char *s = "HelloWorld! "; //定义一个常量字符串
char * addr = kstrndup( s, 6, GFP_KERNEL); //调用函数,分配模式为GFP_KERNEL
printk("addr = 0x%lx\n", (unsigned long)addr); //将字符串s拷贝到内存中的起始地址
printk("*addr = %c\n", *addr); //输出第一个字符
printk("*addr+4 = %c\n", *(addr+4)); //输出第五个字符
for(temp = addr; *temp ! ='\0'; temp ++) //循环地址中的字符值
printk("%c", *temp);
printk("\n");
return 0;
}
模块退出函数:
void __exit kstrndup_exit(void)
{
printk("exit ok! \n");
}
模块初始化及退出函数调用:
module_init(kstrndup_init);
module_exit(kstrndup_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod kstrndup.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。
结果分析:
该测试程序中首先定义了一个常量字符串char * s =“HelloWorld! "
,将其作为参数传递给kstrndup( )函数,同时将len设置为6,目的是为该字符串分配一个内存空间,并将其拷贝到该内存空间中(拷贝的字符串最多为前6字节)。然后输出addr的值可看到所分配的内存空间的起始地址,再输出地址偏移为0和4处的内容,依次为’H’
和’o'
,最后循环输出地址中的字符值,为“HelloW”
,可知原字符串已经被分配空间,并且成功完成前6字节的拷贝。