1
typedef struct 
{
     uint32_t field_id;
     uint16_t length;
}entry_t;


struct node
{
        entry_t *sp_entry;
        struct node *next;
}*head;

リンクリストにエントリを追加するadd()という関数があります。

void add( entry_t *entry )
{
        struct node *temp;
        temp=(struct node *)malloc(sizeof(struct node));
        temp->sp_entry = entry;
        if (head== NULL)
        {
                head=temp;
                head->next=NULL;
        }
        else
        {
                temp->next=head;
                head=temp;
        }
}

リンクリストノードに格納されている「値」自体が構造体へのポインタであることに注意してください。セグメンテーション違反が発生しています。

temp->sp_entry = entry;

これはおそらく、entry_t構造体の割り当てメモリではないためです。知りたいのは、これが通常のユースケースであるということです。はいの場合、どうすればよいですか。

temp->sp_entry = malloc(sizeof (entry_t));

割り当てを行う前に?また、これを達成するためのよりエレガントな方法はありますか?

追加情報。

gdbを実行すると、

p *temp
$3 = {sp_entry = 0x0, next = 0x3e64656269}      

sp_entryはnullポインタのように見えます。これはadd()関数のmallocの後に出力されます。また、私のコードは「-g-O0-Wall」と結合されています。警告はありません。

4

3 に答える 3

2

コードは問題ないようです。前の行でtemp->sp_entry = entry;割り当てたので、セグメンテーション違反は発生しません。temp

ポインタエラーは潜行性である可能性があります。クラッシュする回線は、必ずしも障害のある回線ではありません。add()正しく見えるので、プログラムの実行の早い段階で、プログラムがすぐにクラッシュしないエラーがあると思われます。

gdbを実行すると、次のようになります。

p *temp
$3 = {sp_entry = 0x0, next = 0x3e64656269}      

sp_entryはnullポインタのように見えます。

問題ない。初期化していないtemp->sp_entryか、temp->nextまだ設定されていないため、それらの値は無意味です。

重要なのはtempの価値です。gdbはを出力できるため、これは有効なポインタのようです*temp。これは本当にセグメンテーション違反が発生している場所ですか?tempgdbが無効なメモリ位置へのポインタであると文句を言い、印刷を拒否することを期待していました*temp

于 2012-10-02T01:56:07.150 に答える
2

コメントを投稿するのに十分なカルマ(?)がないので、これを回答として投稿してください...

unixyシステムを使用している場合は、Valgrind(http://valgrind.org/)を実行して、問題のあるメモリの読み取り/書き込みを確認してください。

于 2012-10-02T02:14:51.917 に答える
1

コードは問題ないようです。セグメンテーション違反を引き起こす唯一の方法は、mallocがnullまたは無効な値を返した場合です。使用する前に、mallocから返された値にnullがないかどうかを確認することをお勧めします。

于 2012-10-02T04:04:25.280 に答える