2

わかりましたので、私はcの構造体にまったく慣れていません。私には非常に奇妙に思える問題があります。
ポインターを使用して単純な構造体を関数に渡すと、構造体はその関数の他の引数の 1 つを新しいデータとして自動的に受け取ります。なぜこれが起こるのかわかりません..現時点では、 move_walker() は何もしないはずですよね?

typedef struct {
    int x,
        y;
} walker_t;

walker_t* init_walker(int x, int y) {
    walker_t walker;
    walker.x = x;
    walker.y = y;
    walker_t *pointer = malloc(sizeof(walker));
    pointer = &walker;
    return pointer;
}

int move_walker(walker_t * walker, int direction) {
    return 0;
}

walker_t* walker;
walker = init_walker(8,2);

printf("%d %d\n", walker->x, walker->y); //will print '8 2'
move_walker(walker, 3);
printf("%d %d\n", walker->x, walker->y); //will print '0 3'

(問題ではないことは確かですが、このコードは実際には複数のファイルに分散されています。)

4

6 に答える 6

3

スタックローカル変数へのポインターinit_walkerを返すため、間違っていますwalker。その変数のメモリは、init_walker終了すると再利用されます。変数の値はスタック上でまだ変更されていないため、最初printfのものは偶然のように機能します。walkerただし、その後関数呼び出しを行うとすぐに、元のinit_walker呼び出しのスタック フレームが上書きされ、walkerポインターがランダムなガベージを指すようになります。

mallocの中にいるときinit_walkerは、すでにwalker_t. したがって、代わりにこれを行う必要があります。

walker_t* init_walker(int x, int y) {
    walker_t *pointer = malloc(sizeof(walker_t));
    pointer->x = x;
    pointer->y = y;
    return pointer;
}
于 2013-02-19T11:49:01.923 に答える
3

問題は、バグがあるwalkerため、ポインターが無効なスタック メモリに移動することです。スタック上に構造体を作成し、メモリを予約して、そのメモリのアドレスを に割り当てます。ここまでは順調ですね。init_walkerwalker_tmallocpointer

ただし、この行pointer = &walkerは構造体をスタックから新しいメモリにコピーするのではなくpointer、スタック上の構造体を指すようにします! &walkerのアドレスでありwalker、それをポインタに割り当てます。おそらくやりたいことは、構造体をコピーすることです。そのためには、ポインターを逆参照する必要があります。

*pointer = walker

これにより、プログラムが意図したとおりに機能するはずです。スタック上の構造体を完全にスキップすることもできます:

walker_t* init_walker(int x, int y) {
    walker_t *walker = malloc(sizeof(walker_t));
    walker->x = x;
    walker->y = y;
    return walker;
}
于 2013-02-19T11:50:37.067 に答える
2

スタック上に構造体オブジェクトを作成しています。を使用して割り当てる必要があります

walker_t* init_walker(int x, int y) {
walker_t* walker = malloc(sizeof(walker_t));
...
return walker;
}

walker_t *pointer = malloc(sizeof(walker));
pointer = &walker;

あなたはメモリリークを作成しています!&walker をポインターに割り当てると、新しいメモリを *pointer に割り当て、ポインターを失います。

于 2013-02-19T11:48:17.660 に答える
0

あなたのコードはそれを「非常に奇妙な」政体にすることです。

これはうまくいくでしょう...

walker_t *init_walker (int x, int y)
{
    walker_t *p_walker = (walker_t *)malloc (sizeof(walker));

    if (p_walker != NULL)
    {
        p_walker->x = x;
        p_walker->y = y;
    }
    return (p_walker);
}

free (walker)それからあなたがそれらを終えたら電話してください

于 2013-02-19T11:55:47.073 に答える
0

...または、コードの健全性チェックの後、次のように書くこともできます。

typedef struct 
{
    int x,
    int y;
} walker_t;

void init_walker(walker_t* obj, int x, int y) 
{
   obj->x = x;
   obj->y = y;
}

walker_t walker;
init_walker(&walker, 8,2);
于 2013-02-19T13:00:11.740 に答える
0
 walker_t* init_walker(int x, int y) {
    walker_t walker;
    walker.x = x;
    walker.y = y;
    walker_t *pointer = malloc(sizeof(walker));
    *pointer = walker;  /* here was the error. Copy the value not the adress */
    return pointer;
}

しかし、それはより簡単にすることができます:

walker_t* init_walker(int x, int y) {

    walker_t *pointer = malloc(sizeof(*pointer));
    pointer->x = x;
    pointer->y = y;       
    return pointer;
}
于 2013-02-19T11:49:29.567 に答える