2012-01-15 248 views
3

我是C新手,因此請在這個問題中糾正任何問題,而且我的問題也可能太模糊了。我有這樣的代碼,我得到了分段錯誤。我在網上讀了段故障通常發生當u訪問指向什麼C中的指針和分段錯誤?

struct apple get(char* name) { 
    struct apple a; 
    a.name = name; 
    return a; 
} 
struct apple* read(){ 
    struct apple* ap = (struct apple*)malloc(2*sizeof(struct apple)); 
    ap[0] = get("bob"); 
    return ap; 
} 

// loop through in another function which reads a pointer to an 
// apple object in the array and then accesses apple->name 

當Apple蘋果訪問的指針>名字裏有一個分段錯誤。我假設這是因爲蘋果對象被聲明爲局部變量,並在稍後由c釋放?我真的不知道爲什麼我會遇到分段錯誤或者如何解決這個問題,或者c如何將釋放結構初始化爲函數中的局部變量。有人能告訴我發生了什麼事,謝謝!

+1

你究竟在哪裏得到錯誤?在示例代碼中沒有行說明apple-> name。 – 2012-01-15 15:49:12

+0

我想你需要提供更多的上下文 - 蘋果如何定義,以及你如何使用這些功能?無論如何,[valgrind](http://valgrind.org)可以幫助您找到像這樣的內存問題的來源。 – James 2012-01-15 15:50:41

+1

將代碼告訴我們「這類事情就像這樣」並沒有什麼幫助。您向我們展示的代碼中沒有任何內容會導致分段錯誤。向我們展示一個展示問題的小型完整程序。 'get()'通過值*返回一個struct *,所以這裏沒有問題。 'read()'返回一個指向堆分配內存的指針;該指針在你明確釋放()之前一直有效。 – 2012-01-15 16:06:05

回答

2

好,分段故障錯誤發生時,指針指向的東西,不一定當指針

沒有什麼錯,你發佈的代碼片段:"bob"char*,對於節目的壽命保持有效,並apple返回由值來完成,這樣你就不會返回一個指針到本地無論是。這個問題很可能出現在從read()返回的蘋果上的代碼中。

+0

您確定「bob」對整個程序保持有效,而不僅僅是read()函數期間嗎?無論如何,我很驚訝得到(「bob」)甚至編譯,因爲「bob」是一個const char *,get()需要一個char *。但那可能只是我。 – 2012-01-15 15:55:43

+0

字符串文字適用於整個程序。 (他們分配在數據部分)。如果我記得正確,它們不是常量。 – asaelr 2012-01-15 15:58:41

+0

我相當確定字符串常量與二進制代碼被分配在同一個段中,所以是的,他們會在程序的整個生命週期中保留下來。將'const char *'傳遞給'char *'不會在C中觸發警告(我在gcc中驗證過它)。 – dasblinkenlight 2012-01-15 16:02:28

0

我想你會嘗試更改字符串。在C中,字符串文字應該是隻讀的,並且試圖改變它們是未定義的行爲。如果你想讓a.name不是隻讀的,你可以使用strdup。 (並且不要忘記釋放它)

1

以後再讀ap[0].name(其中ap是由read()返回的指針)沒有任何錯誤。

另一方面,讀取ap[1].name是未定義的行爲,因爲您從未初始化它。

另外,修改指向ap[0].name的字符串是不允許的,因爲它指向一個字符串文字。

0

我不是很經驗以C自己,但我可以在被嚴重downvoted的風險接聽它採取了一槍..

我認爲問題是,你在堆中分配內存在錯誤的地方。據我所知,你的意圖是get返回一個新的apple結構與提供的名稱?在這種情況下,您應該在get方法中分配內存,然後返回struct apple *。因此,一些

struct apple *get(char* name) { 
    struct apple *ap = (struct apple *) malloc(sizeof(struct apple)); 
    ap->name = name; 
    return ap; 
} 
+0

返回結構是完全合法的(但不是推薦)。 返回值是局部變量的副本。 (例如,就像它是一個int)。 – asaelr 2012-01-15 15:54:31