簡體   English   中英

從函數C返回填充的字符串數組

[英]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]" 
}

我的問題:如何最好地以安全且一致的方式執行此操作。 專業人士如何做到這一點?


  1. 我不使用malloc是因為:

    • 我不知道輸入的參數數量或每個參數的長度(動態分配空間)。 我知道這就是為什么我使用指針
    • 因為我在main函數中聲明了它,所以我認為argCTempargVTemp所使用的指向/內存的指針在范圍內就可以了,即使它們在堆棧中也可以。
  2. 我知道myFunc退出時會使它創建的任何堆棧引用無效,所以這就是為什么我從調用函數向其發送了指針。 我應該使用指針和malloc等等嗎?

  3. 最后一件事:在myfunc退出之前,我檢查以查看argCTempargVTemp的值以及它們是否具有有效的內容。 我正在這樣設置argCtempargVtemp

     (*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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM