[英]Returning populated string array from function C
这是第一次发布,因此给您带来的任何困惑我深表歉意:
我在写这样的函数:
int myFunc(char* inputStr, int *argCTemp, char** argVTemp[]);
我函数的目的是获取输入字符串的副本(基本上是任何用户输入),然后使用strtok
将其转换为令牌,并通过数组指针( argV
)填充数组。 当myFunc
完成时,希望我可以从我的inputStr
字符串中获取参数计数和字符串数组。
这是我如何称呼它的一个例子:
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
结束并由调用函数读取时,它仍然变得很垃圾。
由于“不知道输入的参数数量或每个参数的长度”,因此还可以使用malloc
。 当你的缓冲abouting满,你应该realloc
你的缓冲区。 更好的方法:您不必存储整个输入。 行,令牌或块更好。 只需设置一个静态数组即可存储它们。 如果您输入的内容超过100 mb,则哈希值可能会更好。
您向该函数发送一个未初始化的指针(调用也不正确,不需要&),该指针指向某个随机位置,这就是为什么会出现垃圾的原因,也可能导致分段错误。
您可以做两个之一。
每个分配足够大的数组,例如可以是静态的
static char * arr[MAX SIZE]
并在函数调用中将其发送(char **)&arr
,或者运行两次并使用malloc。
您还应该传递最大大小,或使用常量并确保不传递它。
假设您在int n
的令牌数量
char * arr [] = malloc(sizeof(int *)* n);
这将创建一个指针数组,现在您通过调用将其传递给填充函数
与(char **)&arr
使用,并像在代码中一样使用它
例如(*argVTemp)[0] = ;
。
(当不再需要该数组时,请不要忘记通过校准free(arr)来释放它)
一般而言,由于您不知道结果中将包含多少个令牌,因此需要使用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()
的简单包装器,但是这使您可以灵活地执行更复杂的事情(例如为令牌分配内存,因此您不必破坏输入字符串)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.