我需要能够在内核模块中检查文件描述符,dentry或inode是否属于某个路径。为此,我将不得不编写一个函数,当给定dentry或文件描述符(不确定哪个)时,将返回所述对象的完整路径名。
编写返回可变长度字符串的函数的方法是什么?
答案 0 :(得分:3)
您可以尝试这样:
char *myFunction(void)
{
char *word;
word = malloc (sizeof (some_random_length));
//add some random characters
return word;
}
您还可以参考相关主题:best practice for returning a variable length string in c
答案 1 :(得分:3)
在C中执行此操作的典型方法是不返回任何内容:
void func (char* buf, size_t buf_size, size_t* length);
其中buf
是指向缓冲区的指针,该缓冲区将保存由调用者分配的字符串。 buf_size
是该缓冲区的大小。 length
是函数使用的缓冲区的多少。
您可以返回指向buf
的指针,例如strcpy
。但这并没有多大意义,因为其中一个参数中已存在相同的指针。它只会增加混乱。
(不要使用strcpy,strcat等函数作为如何编写函数的一些角色模型。许多C标准库函数都有模糊的原型,因为它们非常古老,从良好的编程实践时间开始#&# 39; t发明,或至少不为Dennis Ritchie所知。)
答案 2 :(得分:2)
有两种常见的方法:
一种是使用固定大小的缓冲区来存储结果:
int makeFullPath(char *buffer,size_t max_size,...)
{
int actual_size = snprintf(buffer,max_size,...);
return actual_size;
}
使用此方法的标准函数示例包括strncpy()
和snprintf()
。这种方法的优点是不需要动态内存分配,这将为时间关键功能提供更好的性能。缺点是它会给调用者更多的责任,以便能够提前确定最大可能的结果大小,或者在需要更大的大小时准备好重新分配。
第二种常用方法是计算使用缓冲区的大小并在内部分配这么多字节:
// Caller eventually needs to free() the result.
char* makeFullPath(...)
{
size_t max_size = calculateFullPathSize(...);
char *buffer = malloc(max_size);
if (!buffer) return NULL;
int actual_size = snprintf(buffer,max_size,...);
assert(actual_size<max_size);
return buffer;
}
使用此方法的标准函数的示例是strdup()
。优点是调用者不再需要担心大小,但他们现在需要确保他们释放结果。对于内核模块,您可以使用kmalloc()
和kfree()
代替malloc()
和free()
。
不常见的方法是使用静态缓冲区:
const char *makeFullPath(char *buffer,size_t max_size,...)
{
static char buffer[MAX_PATH];
int actual_size = snprintf(buffer,MAX_PATH,...);
return buffer;
}
这可以避免调用者不得不担心大小或释放结果,并且它也很有效,但它有一个缺点,调用者现在必须确保他们不会在第二次调用该函数时第一次通话的结果仍在使用中。
char *result1 = makeFullPath(...);
char *result2 = makeFullPath(...);
printf("%s",result1);
printf("%s",result2); /* oops! */
这里,调用者可能打算打印两个单独的字符串,但它们实际上只是获得第二个字符串两次。这在多线程代码中也存在问题,并且可能无法用于内核代码。
答案 3 :(得分:0)
例如:
char * fn( int file_id )
{
static char res[MAX_PATH];
// fill res[]
return res;
}
答案 4 :(得分:0)
/*
let do it the BSTR way (BasicString of VB)
*/
char * CopyString(char *str){
unsigned short len;
char *buff;
len=lstrlen(str);
buff=malloc(sizeof(short)+len+1);
if(buff){
((short*)buff)[0]=len+1;
buff=&((short*)buff)[1];
strcpy(buff,str);
}
return buff;
}
#define len_of_string(s) ((short*)s)[-1])
#define free_string(s) free(&((short*)s)[-1]))
int main(){
char *buff=CopyString("full_path_name");
if(buff){
printf("len of string= %d\n",len_of_string(buff));
free_string(buff);
}else{
printf("Error: malloc failed\n");
}
return 0;
}
/*
now you can imagine how to reallocate the string to a new size
*/