用C编写一个通用的功能,如何处理字符串 [英] Writing a generic function in C, how to handle strings
问题描述
我有一个函数,需要一个无效**
参数和一个整数,指示其数据类型
I have a function that takes a void**
argument and an integer that indicates its datatype
void foo (void** values, int datatype)
在函数内部,根据不同的数据类型,我这样的malloc吧:
Inside the function, depending on the datatype, I malloc it this way:
if (datatype == 1)
*values = (int*) malloc (5 * sizeof(int));
else if (datatype == 2)
*values = (float*) malloc (5 * sizeof(float));
所有这些都是好的,现在高达。然而,当字符串进入图片,事情就变得复杂了。在无效**
将需要无效***
,因为我需要做这样的事情:
All is good upto now. However, when character strings come into the picture, things get complicated. The void**
would need to be void***
, since I will need to do something like this:
*values = (char**) malloc (5 * sizeof(char*));
for(i=0;i<5;i++)
(*values)[i] = (char*) malloc (10);
..
strncpy( (*values)[0], "hello", 5);
应该如何这样的情况如何处理?
我可以通过一个字符***
给需要的功能的无效**
,但投它正确里面呢?
How should such a situation be handled?
Can I pass a char***
to the function that expects a void**
but cast it correctly inside it?
void foo (void** values, int datatype) {
if(datatype == 3) {
char*** tmp_vals = (char***) values;
*tmp_vals = (char**) malloc (5 * sizeof(char*));
...
(*tmp_vals)[i] = (char*) malloc (10 * sizeof(char));
strncpy ( (*tmp_vals)[i], "hello", 5);
}
于是我就投了无效**
到字符***
。我尝试这样做,忽略了警告,它工作得很好。
但是,这是安全的吗?有没有更优雅的替代方案?
So I just cast the void**
into a char***
. I tried this and ignoring the warnings, it worked fine.
But is this safe? Is there a more graceful alternative?
推荐答案
您不需要(可能不应该)使用无效**
在所有 - 只需使用普通的无效*
。每C11 6.3.2.3.1,一个指针空隙
可被转换成或从一个指针到任何对象类型,一个指针到任何对象类型可被转换成一个指针无效
,然后再返回;结果应比较等于原始指针。指针变量,包括一个指向另一个指针,是一个对象。 无效**
不是一个指向无效
。您可以自由安全地转换,并从无效*
,但你不能保证能够安全地转换,并从无效**
。
You don't need to (and probably shouldn't) use a void **
at all - just use a regular void *
. Per C11 6.3.2.3.1, "a pointer to void
may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void
and back again; the result shall compare equal to the original pointer." A pointer variable, including a pointer to another pointer, is an object. void **
is not "a pointer to void
". You can convert freely and safely to and from void *
, but you're not guaranteed to be able to convert safely to and from void **
.
所以,你可以这样做:
void foo (void* values, int datatype) {
if ( datatype == 1 ) {
int ** pnvalues = values;
*pnvalues = malloc(5 * sizeof int);
/* Rest of function */
}
等等,然后调用它类似于:
and so on, and then call it similar to:
int * new_int_array;
foo(&new_int_array, 1);
&放大器; new_int_array
的类型 INT **
,这将让隐式转换为无效*
按富()
和富()
将其转换回键入 INT **
并取消对它的引用间接修改 new_int_array
来指向它动态分配新的内存。
&new_int_array
is of type int **
, which will get implicitly converted to void *
by foo()
, and foo()
will convert it back to type int **
and dereference it to indirectly modify new_int_array
to point to the new memory it has dynamically allocated.
有关一个指向字符串动态数组:
For a pointer to an dynamic array of strings:
void foo (void* values, int datatype) {
/* Deal with previous datatypes */
} else if ( datatype == 3 ) {
char *** psvalues = values;
*psvalues = malloc(5 * sizeof char *);
*psvalues[0] = malloc(5);
/* Rest of function */
}
等,并将其命名为:
and so on, and call it:
char ** new_string_array;
foo(&new_string_array, 3);
同样,&放大器; new_string_array
的类型字符***
,再次被隐式转换为无效*
和富()
将其转换回和间接品牌 new_string_array
点到的存储器中的新分配的块。
Similarly, &new_string_array
is type char ***
, again gets implicitly converted to void *
, and foo()
converts it back and indirectly makes new_string_array
point to the newly allocated blocks of memory.
这篇关于用C编写一个通用的功能,如何处理字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!