[英]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]
訪問newHead
和newTail
。
您還需要將copyPath
的返回類型copyPath
為stuct path **
,例如
struct path **copyPath(struct path *head)
並更新呼叫者中的類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.