[英]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;
}
這里的問題是您要返回一個指向局部變量的指針。 一旦在函數中定義了局部變量,它們就會超出范圍。 這意味着您返回的指針將在函數返回后指向未分配的內存。 使用該指針將導致不確定的行為 。
有三種解決方法:
static
局部變量。 它的壽命也將等於程序。 點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
),並能夠逐步執行程序並顯示各種局部變量。
為了完整性(特別是在Linux上),只有當您成為C語言專家之后 ,您才可以考慮使用Boehm的保守垃圾收集器 (請參閱此鏈接 ):然后您將使用GC_malloc
而不是malloc
並且無需顯式free
已分配的指針區域。 Boehm收集器可能(也許以后,尤其是在較大的程序中)“神奇地”為您釋放了內存。 但是了解垃圾收集和引用計數 (由於它不能很好地管理循環引用 ,因此可以看作是不良的GC形式),這很有用。 您也可以設計自己的GC(艱巨的任務),就像我在qish或MELT中所做的那樣 ...
您在create函數中在堆棧上本地創建了stu。 從該函數返回時,將彈出堆棧,使指針指向的數據無效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.