这是第一次发帖,所以我为任何困惑道歉:
我正在写一个这样的函数:
int myFunc(char* inputStr, int *argCTemp, char** argVTemp[]);
我的函数的目的是获取输入字符串的副本(基本上是任何用户输入),然后使用strtok
将其转换为标记并通过数组指针填充数组(argV
)。当myFunc
完成时,希望我有inputStr
字符串中的参数count和字符串数组。
以下是我如何称呼它的示例:
int main(int argc, char** argv[])
{
int argCTemp = -1;
char** argVTemp;
// 1 Do Stuff
// 2 Get input string from user
// 3 then call myfunc like this:
myFunc(inputStr, &argCTemp, &argVTemp);
// 4: I get garbage whenever I try to use "argVTemp[i]"
}
我的问题:我应该如何以安全和一致的方式做到最好。专业人士如何做到这一点?
我不使用malloc
因为:
argCTemp
和argVTemp
使用的指针/内存很好/保留在范围内,即使它们在堆栈中也是如此。我知道当myFunc
退出时它会使它创建的任何堆栈引用无效,所以这就是我从调用函数发送指针的原因。我应该使用指针和malloc
等等或什么?
最后一件事:在myfunc
退出之前,我会查看argCTemp
和argVTemp
的值,并且它们包含有效内容。我正在设置argCtemp
和argVtemp
,如下所示:
(*argCTemp) = argCount;
(*argVTemp)[0] = "foo";
并且在函数退出之前似乎工作得很好。由于我在内存中的其他位置设置指针,我很困惑为什么引用失败。我在设置指针时尝试使用malloc
INSIDE myFunc
,当myFunc
结束并且被调用函数读取时它仍然变为垃圾。
答案 0 :(得分:1)
由于“不知道我的输入的参数数量或每个参数的长度”,您也可以使用malloc
。当你的缓冲区满员时,你应该realloc
你的缓冲区。
更好的方法:您不需要存储整个输入。一条线,一个标记或一个块更好。只需设置一个静态数组来存储它们。如果你的输入超过100 mb,也许散列更好。
答案 1 :(得分:0)
一般来说,由于您不知道结果中将包含多少令牌,因此您需要使用malloc()
,realloc()
和/或某些等效项动态分配数组。或者,您可以让调用者在数组中传递数组的大小,如果数组不够大,则返回错误指示(对于动态分配不合适的嵌入式系统上的简单命令解析器,我这样做。)
这是一个以小增量分配返回数组的示例:
static
char** myFunc_realloc( char** arr, size_t* elements)
{
enum {
allocation_chunk = 16
};
*elements += allocation_chunk;
char** tmp = (char**) realloc( arr, (*elements) * sizeof(char*));
if (!tmp) {
abort(); // or whatever error handling
}
return tmp;
}
void myFunc_free( char** argv)
{
free(argv);
}
int myFunc(char* inputStr, int *argCTemp, char** argVTemp[])
{
size_t argv_elements = 0;
size_t argv_used = 0;
char** argv_arr = NULL;
char* token = strtok( inputStr, " ");
while (token) {
if ((argv_used+1) >= argv_elements) {
// we need to realloc - the +1 is because we want an extra
// element for the NULL sentinel
argv_arr = myFunc_realloc( argv_arr, &argv_elements);
}
argv_arr[argv_used] = token;
++argv_used;
token = strtok( NULL, " ");
}
if ((argv_used+1) >= argv_elements) {
argv_arr = myFunc_realloc( argv_arr, &argv_elements);
}
argv_arr[argv_used] = NULL;
*argCTemp = argv_used;
*argVTemp = argv_arr;
return argv_used;
}
一些注意事项:
myFunc_free()
来释放返回的数组。目前这是free()
的简单包装器,但是这使您可以灵活地执行更复杂的操作(例如为令牌分配内存,这样您就不必销毁输入字符串)。