[英]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.