2012-09-17 59 views
0

在這段代碼中,我試圖創建一個列表,其中包含所有的字符形式的輸入文件,我的主要問題是與句子「你不能返回一個局部變量的功能「我被告知這讓我很困惑。我動態分配一個列表並返回它,我可以只定義List list沒有動態分配並返回它?我相信這是因爲所有的信息都會被自動刪除,我只會留下我創建的原始列表的地址。動態分配和返回一個局部變量

下面是詳細信息代碼:

typedef struct Item { 
    char tav; 
    struct Item* next; 
} Item; 

typedef struct List { 
    Item* head; 
} List; 

List* create(char* path) { 
    FILE* file; 
    List* list; 
    Item* trav; 
    Item* curr; 
    char c; 

    file=fopen(path, "r"); 
    if (file==NULL) { 
     printf("The file's not found"); 
     assert(0); 
    } 

    if (fscanf(file, "%c", &c)!=1) { 
     printf("The file is empty"); 
     assert(0); 
    } 
    trav=(Item *)calloc(1, sizeof(Item)); 
    trav->tav=c; 
    list=(List *)calloc(1, sizeof(List)); /* allocating dynamiclly the list so it won't be lost at the end of the function*/ 
    list->head=trav; 

    while (fscanf(file, "%c", &c)==1) { 
     curr=(Item*)calloc(1, sizeof(Item)); 
     curr->tav=c; 
     trav->next=curr; 
     trav=curr; 
    } 
    trav->next=NULL; 

    fclose(file); 

    return list; 

} 

,對嗎?這是必要的嗎?我可以定義List而不是指向一個返回的指針嗎?

回答

1

您不能返回指向該函數局部變量的指針。局部變量不會超出函數的範圍({,})。
返回函數本地變量的地址會給你所謂的未定義的行爲

可以很好的回報:

  • 局部變量的值或
  • 一個指針指向動態分配的內存

傾向於第一種,除非你真正困擾約overhaed內存由於返回副本。

我可以直接定義沒有動態分配的列表並返回它嗎?

是,
只要你有:

List create(char* path); 
+0

謝謝你的回答。在我的情況下返回非動態分配的列表也不錯?我的意思是如果我的主要功能將它用作「List list = create(file)」? – Joni

+0

@Joni,是的,沒關係。 – Shahbaz

1

不能返回函數

的局部變量這句話是完全錯誤的。例如,在此功能中:

int f(void) 
{ 
    int x = 5; 
    return x; 
} 

是一個完全有效的函數,在該函數中返回一個局部變量。

你應該知道的是,你不能(或更好說應該)返回函數的局部變量的地址。這是因爲函數返回地址指向垃圾並且不再可用。

在您的示例中,您可以非常安全地定義本地List並將其返回。

請注意,您仍然需要動態分配trav,即出於上述相同原因,您不能採用類型爲Item的局部變量以及要點list->head

+0

您正在將一份副本返回到當地的變量。 – moooeeeep

+0

@moooeeeep,我相信這是暗示的。否則,「返回一個局部變量」是什麼意思? – Shahbaz

+0

我在這個練習中被告知「創建的列表必須通過函數的參數返回」 - 這是什麼意思?你認爲我想創建「void create(&list,file)」函數嗎? – Joni