0

このプログラムの重大なエラーのないフローに不要な場合、効率、さらにリストへのアクセス可能性、または free() 関数の欠如について尋ねているのではありません。

#include <stdlib.h>


typedef struct a
{
    a * nast;
    double v;

};

void add(struct a* list,double d)
{
    list = (a*)malloc(sizeof(a));

    if(!list->nast) goto exception;

    list=list->nast;

    list->v=d;

    return;

exception:
    printf("Cannot add to the list \n");
}


int main()
{
    struct a l;

    add(&l,-602.1);

    return 0;
}

問題は、なぜそれがスローされるのかです

list.exe の 0x000000013f84107a で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0xffffffffffffffff。

実行時エラーとその修正方法

4

3 に答える 3

2

このコードには非常に多くの問題があるため、ポインターと引数の受け渡しについて詳しく読んだほうがよいと思います。ただし、いくつかの点があります。

  • 関数で「リスト」を宣言すると、mainすでにスタックに割り当てられています。次に、関数でそれを新たに割り当てようとしaddます。

  • 関数内でノードを割り当てたい場合は、add参照によってポインターを渡す必要があります。つまり、ポインターへのポインターです。これは、それ以外の場合、ポインターが値で渡され、関数が戻るときにポインターへのすべての変更 (つまり、ポインターが指すものではなく、実際のポインター) が失われるためです。

  • このmalloc関数は、割り当てられたメモリをクリアしません。それを自動的に行いたい場合は、calloc関数を使用する必要があります。

  • nastノードをリストにリンクするのではなく、(初期化されていない)ポインターでリストの先頭を上書きするだけです。

  • 構造体でを使用typedefしますが、実際には this の名前を定義しませんtypedef

  • どうぞ、使わないでくださいgoto!使いすぎると、コードを読みにくく、理解するのが非常に難しくなる可能性があります (使いすぎると、多くの人は、一度でも使いすぎると主張します)。


これを行う場合add、リストに追加する値とともに、引数としてポインターへの参照を関数に持たせることになります。次に、その値に新しいノードを割り当て、ポインターが古いリストを指すようにしてリストにリンクしnext、リスト ポインターを新しいノードを指すように再割り当てします。渡されたリストが の場合、リストがNULL新しいノードを指すようにします。

このようなもの:

struct node
{
    struct node *next;
    double       value;
};

void add(struct node **l, const double value)
{
    /* Allocate a new node, use `calloc` to clear the memory automatically */
    struct node *n = calloc(1, sizeof(struct node));

    /* Set the value of the new node */
    n->value = value;

    /* Is the list non-null? */
    if (*l != NULL)
    {
        /* Yes, make the `next` pointer point to the old list */
        n->next = *l;
    }

    /* Make the list point to the new node */
    *l = n;
}

この関数は、次のように呼び出すことができます。

 /* Initialize to `NULL` to mark the list as empty */
struct node *list = NULL;

/* Add two nodes, passing the list pointer by reference */
add(&list, 12.34);
add(&list, 56.78);

リストには 2 つのノードがあります。

  1. リストの最初のノードには値が含まれます56.78
  2. リストの 2 番目のノードには値が含まれます12.34
于 2013-01-08T06:38:46.500 に答える
0

このコードには多くの作業が必要です。ただし、次の行のために例外が発生します。

if(!list->nast) goto exception;

malloc割り当てたメモリをゼロにしません。新しいリスト構造を割り当てますが、ゼロに設定されていないため、そのnastポインターはガベージを保持しています。上記のチェックは失敗し、次の行でこのガベージの参照を解除して例外を取得します。

しかし、実際には、修正したとしても、このコードには作業が必要です。

于 2013-01-08T06:33:18.163 に答える
0

list=list->nast; リストをnullにするため です。

于 2013-01-08T06:33:45.283 に答える