0

C でリンクされたリストがあります。「在庫レベル」に基づいて動的に入力したいと考えています。テスト目的で、小さなプログラムを作成しました。ここでの在庫レベルは単純に 1 にハード コードされていますが、実証するには十分です。

このコードでは、リンク リストの最初のノードが特別なので、自分で作成し、常に同じままにします。残りのノード (「在庫レベル」に一致する数) は動的に作成されます。

問題がスコープに関係していることは知っていますが、その方法は本当にわかりません。

「在庫レベル」を 0 に設定すると、すべて正常に動作します。出力は次のようになります。

 inside function: (5, 10)
outside function: (5, 10)

「在庫レベル」を 1 に上げると、出力は次のようになります。

 inside function: (5, 10)  ; Correct
 inside function: (2, 3)   ; Correct
outside function: (5, 10)  ; Still Correct
outside function: (24, 48) ; What..?
outside function: (0, 1)
outside function: (1848777136, 32767)

リンクリストの先頭に行ってみましmallocたが、同様の結果が得られました。mallocまた、各構造体の一部を試してみました.nextが、同様の結果が得られました。私はしばらくの間これを修正しようとしてきましたが、これを処理するためにインライン for ループを実行するだけになりましたが、別の関数に入れたいと思っています (その特定のコードを繰り返す必要があるため)。数か所)。

助けてくれてありがとう。

参考までに、私が使用しているコードは次のとおりです。

#include <stdlib.h>                                                                                                                                       

struct Item {
  int x;
  int y;
  struct Item *next;
};  

void create(struct Item *start, int stock) {
  *start = (struct Item){ .x = 5, .y = 10, .next = NULL };

  int i;
  struct Item *previous = start;
  for (i = 1; i <= stock; i++ ) { 
    previous->next = &(struct Item){ .x = (i*2), .y = (i*3), .next = NULL };
    previous = previous->next;
  }   

  struct Item *node = start;
  while (node != NULL) {
    printf(" inside function: (%d, %d)\n", node->x, node->y);
    node = node->next;
  }   
}   

int main() {
  struct Item head;
  int stock = 1;

  create(&head, stock);

  struct Item *node = &head;
  while (node != NULL) {
    printf("outside function: (%d, %d)\n", node->x, node->y);
    node = node->next;
  }   

  return 0;
}
4

1 に答える 1

2

この線

previous->next = &(struct Item){ .x = (i*2), .y = (i*3), .next = NULL };

forループを終了するとスコープ外になるローカル スタック変数のアドレスを格納します。その後、メモリにアクセスすると、未定義の動作が発生します。考えられる問題の 1 つは、プログラムの他の部分が同じスタックの場所に書き込むことです。

これは、リスト要素にメモリを動的に割り当てることで修正できます

previous->next = malloc(sizeof(*previous->next));
if (previous->next == NULL) {
    /* handle out of memory */
}
*previous->next = (struct Item){ .x = (i*2), .y = (i*3), .next = NULL };

これを行う場合、free後でこのメモリをシステムに返すために呼び出す必要があることに注意してください。

于 2013-08-01T17:17:28.127 に答える