簡體   English   中英

如何在C中返回char **

[英]How to return a char** in C

我已經嘗試了一段時間,但似乎無法正常工作:

char** fetch  (char *lat, char*lon){
  char emps[10][50];
  //char** array = emps;
  int cnt = -1;

  while (row = mysql_fetch_row(result)) 
  { 
    char emp_det[3][20];
    char temp_emp[50] = "";
    for (int i = 0; i < 4; i++){
        strcpy(emp_det[i], row[i]);
    }

    if ( (strncmp(emp_det[1], lat, 7) == 0) && (strncmp(emp_det[2], lon, 8) == 0) ) {

        cnt++;
        for (int i = 0; i < 4; i++){
            strcat(temp_emp, emp_det[i]);
            if(i < 3) {     
                strcat(temp_emp, " ");
            }   
        }
        strcpy(emps[cnt], temp_emp);
    }
  }
}

mysql_free_result(result);
mysql_close(connection);
return array;

是的,我知道array = emps被注釋掉了,但是沒有注釋,它告訴我指針類型不兼容。 萬一我忘了提及,這是在char **類型的函數中,我希望它返回emps [10] [50]或下一個最好的東西。 我該怎么做呢? 謝謝!

類型為T [N][M]的數組表達式不會衰減為T ** -它會類型為T (*)[M] (指向M元素數組的指針)。

其次,您嘗試返回該函數本地數組的地址。 函數退出后, emps數組將不再存在 ,並且指向它的任何指針都將變為無效。

您最好將目標數組作為參數傳遞給函數並讓函數對其進行寫入,而不是在函數內創建一個新數組並返回它。 您可以動態分配數組,但是隨后您將進行內存管理,而避免內存管理問題的最佳方法是避免執行內存管理。

所以你的函數定義看起來像

void fetch( char *lat, char *lon, char emps[][50], size_t rows ) { ... }

和您的函數調用看起來像

char my_emps[10][50];
...
fetch( &lat, &lon, my_emps, 10 );

即使嘗試進行強制轉換,您嘗試執行的操作也不起作用,因為您將返回局部變量的地址。 當函數返回時,該變量超出范圍,並且所使用的內存不再有效。 嘗試取消引用該地址將導致未定義的行為。

您需要使用動態內存分配來創建要返回的數據結構:

char **emps;
emps = malloc(10 * sizeof(char *));
for (int i=0; i<10; i++) {
    emps[i] = malloc(50);
}
....
return emps;

調用函數將需要free此函數創建的內存。 它還需要知道完成了多少分配,因此它知道有多少次調用free

如果您找到了一種轉換char emps[10][50]; 變成一個char *char **

  • 您將無法正確映射數據(尺寸等)。 多維char數組不是char ** 它們只是具有索引計算的連續內存。 更好地適合char * BTW
  • 但是最大的問題是emps超出范圍,並且自動內存將重新分配給其他變量,從而破壞了數據。

但是,如果尺寸確實固定,有一種方法可以做到:

您可以創建一個將char[10][50]作為輸入/輸出參數的函數(您不能返回數組,編譯器不允許,您可以返回包含數組的結構,但這效率不高。 )

例:

void myfunc(char emp[10][50])
{
   emp[4][5] = 'a';  // update emp in the function

}

int main()
{
   char x[10][50];
   myfunc(x);
   // ...
}

main負責x的內存,該內存以可修改的方式傳遞給myfunc例程:安全,快速(無內存副本)

好的做法:定義一個像這樣的類型type typedef char matrix10_50[10][50]; 它使聲明更具邏輯性。

這里的主要缺點是尺寸是固定的。 如果要對另一個維度集使用myfunc ,則必須復制/粘貼它或使用宏來定義兩者(例如窮人的模板)。

編輯

一個很好的評論表明某些編譯器支持可變數組大小。 因此,您可以在不受約束的數組旁邊傳遞維度:

void myfunc(int rows, int cols, char emp[rows][cols])

經過測試, 僅在C代碼而不是C ++上和gcc 4.9 (可能也在較早版本上)一起使用gcc 4.9 ,不能在包含純C的.cpp文件中使用(但仍勝過繁瑣的malloc/free調用)

為了理解為什么不能做到這一點,您需要了解矩陣在C中的工作方式。

矩陣,假設您的char emps [10] [50]是一個連續的存儲塊,能夠存儲10 * 50 = 500個字符(想象一個包含500個元素的數組)。 當您訪問emps [i] [j]時,它將訪問該“數組”中索引為50 * i + j的元素(拿起一張紙和一支筆以了解原因)。 問題在於該公式中的50是矩陣中的列數,在編譯時可以從數據類型本身得知。 當您擁有char **時,編譯器無法知道如何訪問矩陣中的隨機元素。

構建矩陣以使其成為char **的一種方法是創建一個指向char的指針數組,然后分配這些指針中的每一個:

char **emps = malloc(10 * sizeof(char*)); // create an array of 10  pointers to char
for (int i = 0; i < 10; i++)
    emps[i] = malloc(50 * sizeof(char)); // create 10 arrays of 50 chars each

關鍵是,您無法以將數組轉換為指針的類似方式將矩陣轉換為雙指針。

另一個問題:僅當使用指針數組(每個指針指向一個字符 數組 )實現矩陣時,將2D矩陣返回為'char **'才有意義。 如前所述,C語言中的2D矩陣只是字符的平面數組。 您最多可以返回的是指向[0] [0]條目的指針,即“ char *”。 間接數量不匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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