簡體   English   中英

如何從C中的函數返回指針結構數組

[英]How to return a pointer struct array from a function in C

假設您有一個函數,函數輸出將是鏈表的頭和尾地址(將鏈表復制到另一個地址的函數):

struct path *copyPath(struct path *head) {

  struct path *temp = malloc(sizeof (struct path));  

  // array of newHead and newTail
  struct path *resultPath[2];

  struct path *newHead = NULL;
  struct path *newTail = NULL;    

  while (head != NULL) {
      temp = malloc(sizeof (struct path));
      if (newHead == NULL) {
          // Add a new node to the first of list and save newHead as the beginning of the list
      } else {            
          // Add the other nodes and save the last node address as newTail
      }
      head = head -> next;
  }      

  resultPath[0] = newHead;
  resultPath[1] = newTail;        

  return resultPath;
}

我定義了一個struct path數組,並將其返回。 在主函數中,已定義了一個數組:

struct path *newPath;
newPath = copyPath(path_head, nextNode);

運行它時,newPath中沒有任何內容,它為空。

那么,什么是返回這些地址的最佳方法?為什么我在newPath沒有它?

另外,當我使用時:

struct path *newPath[2];
newPath = copyPath(path_head, nextNode);

我有一個錯誤: error: assignment to expression with array type

如何將這兩個值傳遞給主函數?

每當您分配動態內存(使用malloc,calloc,realloc)時,都應將返回地址適當地類型轉換為正確的數據類型。 因為這些函數返回void指針。 在下面的行中,您正在將void指針類型的地址分配給struct path類型的指針。

temp = malloc(sizeof(結構路徑));

它可以寫成:

temp =(結構路徑*)malloc(sizeof(結構路徑));

第二件事,您正在返回類型為“ struct path”的指針數組,但是您正在使用main違反C標准的main類型為“ struct path”的常規指針收集此指針值的返回數組。 更正此錯誤,然后嘗試運行代碼。

在Main中使用指針數組來收集返回值:

結構路徑* newPath [2];

newPath = copyPath(path_head,nextNode)

除注釋外,您的功能還有兩個主要問題:1)通過覆蓋分配的第一個內存塊的地址來泄漏內存; 和2)您嘗試返回returnPath ,該方法具有聲明為copyPath本地的自動存儲持續時間。

內存泄漏

通過在分配指針temp之前覆蓋指針temp ,可以在函數中泄漏內存,例如

struct path *temp = malloc(sizeof (struct path));  
...
while (head != NULL) {
    temp = malloc(sizeof (struct path));

通過在將原始指針分配給另一個變量之前為temp分配第二次時間,可以丟失temp指向分配的第一個內存塊的原始指針。 從那時起,您的程序將永遠無法釋放該內存。

返回具有聲明為函數局部的自動存儲的數組

運行它時,newPath中沒有任何內容,它為空。

struct path *resultPath[2]; 聲明一個指向struct path的指針數組 (其中兩個)。 在函數堆棧框架中,將copyPath自動存儲聲明為resultPath的本地存儲。 copyPath返回時,具有自動存儲持續時間的所有局部變量都將被銷毀(釋放函數堆棧幀存儲器以供重新使用)。 C11標准-§6.2.4對象的存儲持續時間明確說明了這一點

1)對象的存儲期限決定了其生存期。 有四個存儲期限:靜態,線程, 自動和已分配。 分配的存儲在7.22.3中描述。

2)對象的生存期是程序執行的一部分,在此期間保證為其保留存儲空間。 一個對象存在,具有恆定的地址33),並在其整個生命周期中保留其最后存儲的值。34) 如果在其生命周期之外引用了一個對象,則該行為是不確定的。 當指針所指向的對象(或剛過去的對象)達到其生命周期的終點時,指針的值將變得不確定。

6)對於這樣一個不具有可變長度數組類型的對象,其生存期從進入與之相關聯的塊開始,直到該塊的執行以任何方式結束

強調我們的

那么,什么是返回這些地址的最佳方法?為什么我在newPath中沒有它?

為了返回resultPath,您需要為其動態分配存儲並返回指向它的指針。 分配了存儲時間的對象會延長程序的生命周期,或者直到釋放它們為止。

聲明和分配能夠存儲兩個指向struct path指針的對象的最簡單方法是,聲明一個指向struct path的指針 (實際上是一個動態的指針數組),並為兩個指針分配存儲空間,例如

/* allocate & validate 2 pointers to struct path */
struct path **resultPath = malloc (sizeof *resultPath * 2);
if (!resultPath) {        /* always validate all memory allocations */
    perror ("malloc resultPath failed.");
    return NULL;
}
...
resultPath[0] = newHead;  /* newHead & newTail must point to allocated memory */
resultPath[1] = newTail;        

return resultPath;

現在,您可以安全地return resultPath並且return resultPath存儲將在返回后resultPath存在,從而消除了對不再可用的內存的訪問。 然后,您分別通過調用者中的newPath[0]newPath[1]訪問newHeadnewTail

您還需要將copyPath的返回類型copyPathstuct path ** ,例如

struct path **copyPath(struct path *head)

並更新呼叫者中的類型。

暫無
暫無

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

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