哦,男孩,從哪裏開始?你真的需要一本好書。嘆。讓我們開始在main()
頂部:
這
struct Player *player;
定義一個指針struct Player
,但它不會初始化。因此,它具有或多或少的隨機價值,指向某個記憶。此
player->name = malloc(sizeof(player->name)*256);
現在寫入該隨機位置的份malloc()
獲得一塊內存的地址。通過未初始化的指針寫入內存調用未定義的行爲。之後,所有投注都關閉。無需再看看你的程序。不幸的是,你偶然會寫入到你的進程所擁有的一塊內存中,所以它不會立即崩潰,讓你意識到這個問題。
有兩種方法可以改善這種情況。要麼堅持指針,並指向分配給Player
對象的一塊內存。你可以致電malloc(sizeof(Player)
來獲得它。
或者只是使用本地,自動(又名基於堆棧的)對象:
struct Player player;
編譯器將生成的代碼的堆棧它上分配內存,並會自動釋放它。這是最簡單的,當然應該是你的默認值。
但是,您的代碼有比這更多的問題。
這
player->name = malloc(sizeof(player->name)*256);
在堆上分配連續的存儲到256個指針存儲字符,並分配所述第一指針的player->name
地址(一個char*
的地址,因此char**
)(一char*
)。坦率地說,我感到驚訝,即使編譯,但我更習慣於C++更嚴格的類型執行。無論如何,你可能就要代替的是爲256個字符分配內存:
player->name = malloc(sizeof(char)*256);
(由於sizeof(char)
,顧名思義,1
,你經常會看到這樣的malloc(256)
。)
然而,有更多的這種:爲什麼是256?如果我傳遞一個1000字符長的字符串會怎樣?不,只是爲更長的字符串分配空間不是解決這個問題的方法,因爲我可以將它傳遞給更長的字符串。因此,要麼1)固定的最大字符串長度(只是聲明Player::name
是一個char
陣列的長度,而不是char*
)並在代碼執行此限制,或2)找出動態所需要的長度,在運行時間,並準確地分配所需的內存(字符串長度加1,終止'\0'
char)。
但它變得更糟。這
player->name = "John";
然後分配給player->name
文字字符串的地址,通過覆蓋在malloc()
你保存它的唯一變量分配的內存的地址,讓你失去的,泄漏的內存。
但是C字符串並不是一流的公民,所以你不能指定它們。它們是字符數組,按慣例以'\0'
結尾。要複製它們,您必須逐個字符地複製它們,無論是循環還是最好通過調用strcpy()
。
要雪上加霜的是,你以後嘗試釋放內存字符串文字生活
free(player);
從而極有可能嚴重擾亂堆管理器的數據結構。再說一遍,你似乎不太幸運,因爲這不會導致立即崩潰,但代碼似乎按照預期工作是未定義行爲最糟糕的可能性之一。如果不是所有的賭注都被剝離,他們現在徹底的會是。
對不起,如果這聽起來譴責,它確實不是這個意思,但你肯定和嚴重搞砸了這一個。爲了總結這件事:
你需要一個良好的C++的書。馬上。 Here是C程序員在Stack Overflow上彙編的好書的列表。 (我是一名C++程序員,所以我不會評論他們的判斷,但是K & R肯定是個不錯的選擇。)
你應該立即初始化所有的指針,或者用現有的地址有效的對象,或分配的內存地址,以保存正確類型的對象,或使用NULL
(稍後可以輕鬆檢查)。特別是,你不能嘗試讀取或寫入一段未分配給你的內存(在堆中動態分配或自動分配給你)。
你需要free()
這是通過調用malloc()
恰好一次獲得的所有內存。
您不能嘗試free()
任何其他內存。
我敢肯定還有更多的代碼,但我會在這裏停止。 我有沒有提到你需要一本好的C書?因爲你這樣做。
來源
2011-09-21 09:41:35
sbi
你需要一本好書。急。 – sbi