簡體   English   中英

返回指向C中結構的指針

[英]returning pointer to a structure in C

該程序返回一個指向結構的指針
當我打印內容時, 名稱顯示不正確,而其他兩個變量也被正確打印。
可能是什么問題呢? 這是C中的代碼

#include<stdio.h>
struct student
    {
        char name[20];
        int marks;
        int rank;
    };
struct student stu;
struct student *create();

void main()
{
    struct student *ptr;
    ptr = create();
    printf("%s\t %d\t %d\t",ptr->name,ptr->marks,ptr->rank);
}

struct student *create()
{
    struct student stu = {"john",98,9};
    struct student *ptrr;
    ptrr = &stu;
    return ptrr;
}

這里的問題是您要返回一個指向局部變量的指針。 一旦在函數中定義了局部變量,它們就會超出范圍。 這意味着您返回的指針將在函數返回后指向未分配的內存。 使用該指針將導致不確定的行為

有三種解決方法:

  1. 使用全局變量,並返回指向該變量的指針。 全局變量的生存期就是程序的生存期。
  2. 使用static局部變量。 它的壽命也將等於程序。
  3. 在需要時動態分配結構,並返回該指針。

點1和點2的問題在於,您只能有一個對象。 如果修改該對象,則具有指向該單個對象的指針的所有位置都將看到這些更改。

第三點是我推薦您的方式。 問題在於,一旦處理完對象,就必須釋放分配的內存。

您將創建一個局部變量stu ,該變量位於函數create() 在函數create()之外,此變量上的指針不正確。

正如約阿希姆·皮勒博格(Joachim Pileborg)回答的那樣,您不應返回指向局部變量的指針。 順便說一句,如果您使用gcc -Wall -g使用最新的GCC進行gcc -Wall -g (例如,啟用幾乎所有警告和調試信息),則應該收到警告。

因此,在實踐中,您應該確定您的create返回一個堆指針,然后采用其調用者正在釋放該指針的約定

 void main() {
   struct student *ptr;
   ptr = create();
   printf("%s\t %d\t %d\t",ptr->name,ptr->marks,ptr->rank);
   free (ptr);
 }

struct student *create() {
  struct student stu = {"john",98,9};
  struct student *ptrr = malloc(sizeof struct student);
  if (!ptrr) { perror("malloc student"); exit(EXIT_FAILURE); }
  *ptrr = stu;
  return ptrr;
}

仔細閱讀有關C動態內存分配手動內存管理內存泄漏malloc(3)手冊頁的Wikipage 如果您有在Linux上進行編碼的運氣,請了解valgrind

PS。 始終測試malloc的結果(針對失敗)。 始終初始化獲取的內存區域(也許使用memset(3) ....清除它)。

附錄:良好習慣

您應該編譯所有警告和調試信息。 如果使用GCC ,請使用gcc -Wall -g編譯,並改進代碼,直到沒有警告為止。

您絕對應該學習如何使用調試器 (在Linux上為gdb ),並能夠逐步執行程序並顯示各種局部變量。

附錄:使用Boehm GC

為了完整性(特別是在Linux上),只有當您成為C語言專家之后 ,您才可以考慮使用Boehm的保守垃圾收集器 (請參閱此鏈接 ):然后您將使用GC_malloc而不是malloc並且無需顯式free已分配的指針區域。 Boehm收集器可能(也許以后,尤其是在較大的程序中)“神奇地”為您釋放了內存。 但是了解垃圾收集和引用計數 (由於它不能很好地管理循環引用 ,因此可以看作是不良的GC形式),這很有用。 您也可以設計自己的GC(艱巨的任務),就像我在qishMELT中所做的那樣 ...

您在create函數中在堆棧上本地創建了stu。 從該函數返回時,將彈出堆棧,使指針指向的數據無效。

暫無
暫無

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

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