2011-03-22 64 views
4

我不知道該如何解釋這一點,但這段代碼的波紋管可以完全編譯,但是當你運行它,SIGSEV。 請問,有誰可以確切地知道我錯了什麼地方? 事實是我希望能夠訪問由如下指標,並在同一時間元素能夠與結構的工作。指向指向頭痛的struct的指針。 。

#include <stdio.h> 
#include <stdlib.h> 

/* This is a struct describing properties of an element */ 
struct element{ 
    int age; 
    char* name; 
}; 

/* This struct contains a pointer to a pointer on a element "struct element" */ 
struct person{ 
    struct element** p; 
    int id; 
}; 

/* Thus function initializes a struct person by allocation memory for it */ 
struct person* init(int size) 
{ 
    struct person* sample = (struct person*)malloc(size*sizeof(struct person)); 
    sample->p = NULL; 
    sample->id = 0; 
    return sample; 
} 

/* use this function to insert a new element in the struct */ 
void insert(struct person* sample, char* _name, int _age) 
{ 
    sample->p[sample->id]->name = _name; /* the program crashes here according to the debugger , but why?? */ 
    sample->p[sample->id]->age = _age; /* of course, this will cause trouble too because it has the same construct as the previous one */ 
    sample->id++; 
} 


/* main entry */ 
int main() 
{ 
    struct person* student = init(10); /* Allocating space for 10 students */ 
    insert(student, "kido", 8); 
    printf("Your name is %s and your age is %d", student->p[0]->name, student->p[0]->age); /* we can't write student->p->name */ 
    return 0; 
} 
+0

「誰能告訴正是」 調試器。 – 2011-03-22 17:32:57

+0

@Piotr:在代碼中看到註釋:「程序根據調試器在這裏進行分割,但是爲什麼?」此外,+1包括完整的代碼。 – nmichaels 2011-03-22 17:36:39

+0

@nmichaels:啊,那我就是盲目的。抱歉。 – 2011-03-22 17:41:51

回答

5

的問題是在代碼行的insert方法,你在問題中標記

sample->p[sample->id]->name = _name; 

無處在你的程序你爲person結構內的p數組分配內存。因此該值始終爲NULL。試圖分配這個值會導致程序崩潰。

要解決此問題,您需要確保p陣列足夠大以容納表達式sample->id提供的索引。最好的方法是使用realloc函數並添加一個字段到person來存儲p數組的大小

下面是一個快速示例。注:錯誤檢查和0初始化內存省略的重要性。

struct person{ 
    struct element** p; 
    size_t length; 
    int id; 
}; 

void insert(struct person* sample, char* _name, int _age) 
{ 
    if (sample->id >= sample->length) { 
    sample->p = realloc(sample->p, sizeof(element*) * sample->id); 
    } 
    ... 
} 

它似乎很奇怪,雖然這個名字和年齡通過sample->id場總是索引。這表明它總是放置在相同的位置,在這種情況下不需要數組。你能詳細說明這是如何起作用的嗎?

+0

謝謝!那是我在那裏犯的一個愚蠢的錯誤。 – Khan2011 2011-03-22 17:49:26

+0

對不起,我不知道我得到你的問題,但由於**元素**是一個結構,即使訪問它的成員像一個數組一樣工作,**年齡**和**名稱**將只是在一個連續的地址。在我的情況下,我有: 因此,訪問**元素**的成員將只是像一個普通的結構。而且因爲我們有動態內存分配,整個事情就像一個動態數組。 如果我把你的問題弄錯了,請賜教。 Regards – Khan2011 2011-03-22 19:04:16

+0

!繼續!在我的情況下,我有: age @ 0x67a1e0 name @ 0x67a1e4 – Khan2011 2011-03-22 19:11:25

0

在您的init()函數設置sample->p = NULL。在你的insert()函數中,你嘗試解引用 - > p成員sample->p[sample->id]->name。既然你沒有指出 - >對任何存儲,你不能解除引用。

+0

Thanks guys !!!它正在工作! – Khan2011 2011-03-22 17:51:18

0
Starting program: /home/nathan/c/seg 

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000400597 in insert (sample=0x601010, _name=0x400730 "kido", _age=8) 
    at seg.c:28 
28   sample->p[sample->id]->name = _name; /* the program craches here according to the debugger , but why?? */ 
(gdb) backtrace 
#0 0x0000000000400597 in insert (sample=0x601010, _name=0x400730 "kido", 
    _age=8) at seg.c:28 
#1 0x0000000000400601 in main() at seg.c:38 
(gdb) p sample->id 
$1 = 0 
(gdb) p sample->p 
$2 = (struct element **) 0x0 

sample->p未正確初始化。如果你看看init,它確實初始化爲NULLsample->p[anything]因此取消引用空指針,導致段錯誤。

+0

+1可愛調試。這很有用!謝謝 – Khan2011 2011-03-22 18:05:45

0

當您調用init()函數時,將爲多個person結構分配內存,並將第一個結構的'p'指針設置爲NULL。

然後嘗試寫的「P」所指向的內存。當然,它仍然是NULL。

考慮您的意見,我不認爲的init()做你想要做的事。它爲人員結構數組分配空間,而不是具有'p'數組的人員。另外,爲什麼雙指針?

重新檢查設計:)我通常做一個白板,或鉛筆和紙,用方框與我的「對象」和我的指針箭頭。它會澄清你的想法,並可能在他們到達代碼之前顯示你的錯誤。

0
struct person* init(int size) 
{ 
    struct person* sample = (struct person*)malloc(size*sizeof(struct person)); 
    sample->p = NULL; // p is a pointer to a pointer which is initialized to NULL 
         // So, it cannot be dereferenced with out pointing to a valid 
         // memory location. 

    // sample -> p = (struct person**) malloc(sizeof(struct *person)); 
    // sample[p] = (struct(person*)) malloc(sizeof(struct person)); 

    // struct** -> struct* -> struct 

    sample->id = 0; 
    return sample; 
} 

而現在,這兩個語句是有效的 -

sample->p[sample->id]->name = _name; 
sample->p[sample->id]->age = _age; 
+0

謝謝,它與JaredPar完全一樣:我試圖訪問結構指針的元素,其值爲NULL。 – Khan2011 2011-03-22 17:50:48