2017-03-24 19 views
-1

私は宿題のためにSnakeのCバージョンを作成しようとしています。私はゲームに必要なすべてのメカを実装しましたが、ダイナミックメモリ割り当てに問題があります。私の「蛇」は、体の部分とその位置のリストとして配列に格納されています。ヘビが果物を食べるなら、ヘビの長さを変えて、別のボディーピースをアレイに加えようとします。私は、ヘビの最終的なサイズを事前に知らないので、reallocを使って配列を長くしようとします。以下は私のコードです。注:これはSIGABRTを引き起こす前に14回の反復で機能します。realloc()を使用しているSIGABRT

#include <stdio.h> 
#include <stdlib.h> 
void moveSnake(int *snakeLength,int direction, int **tableSnake, int extend); 
int checkItems(int **tableSnake, int **items, int itemsSize); 
int selfdestruct(int **tableSnake); 

/* TEST INPUT DATA: 
9 
-5 4 2 
-3 4 1 
-2 4 1 
0 4 2 
1 3 3 
-2 2 1 
0 2 1 
-7 1 1 
-5 1 3 
15 
*/ 

int main() { 
    int xHead = 0; 
    int yHead = 0; 
    int snakeLength = 1; 
    int direction = 1; 

    // creates the snake table 


    int **tableSnake; 
    tableSnake = (int **) calloc(1,1 * sizeof (int *)); 

    for (int i = 0; i < 1; i++) { 
     tableSnake[i] = (int *) calloc(3,3 * sizeof (int)); 
    } 

    tableSnake[0][0] = 0; 
    tableSnake[0][1] = 0; 
    tableSnake[0][2] = 1; 


    // reads all the variables 
    int noItems; 
    scanf("%d", &noItems); 

    int **items; 
    items = (int **) malloc(noItems * sizeof (int *)); 

    for (int i = 0; i < noItems; i++) { 
     items[i] = (int *) malloc(3 * sizeof (int)); 
    } 

    for (int i = 0; i < noItems; i++) { 
     scanf("%d", &items[i][0]); 
     scanf("%d", &items[i][1]); 
     scanf("%d", &items[i][2]); 
    } 


    int noSteps; 
    scanf("%d", &noSteps); 

    // start of run 

    /* 
    * legend: 
    * direction: 1 - up, 2 - down, 3 - left, 4 - right 
    * typesOfItems: 5 - fruit, 6 - turn left, 7 - turn right 
    */ 

    int itemHead = 0; 
    int extend = 0; 

    for (int i = 0; i < noSteps; i++) { 
     moveSnake(&snakeLength,direction,tableSnake,extend); 
     extend = 0; 
     itemHead = checkItems(tableSnake, items, noItems); 

     if(itemHead == -1){ 
      if(selfdestruct(tableSnake) == 1){ 
       snakeLength = 0; 
       break; 
      }; 
     } 
     if (itemHead == 1) { 
      extend = 1; 
     } else if (itemHead == 2) { 
      if(direction == 1){ 
       direction = 3; 
      }else if(direction == 2){ 
       direction = 4; 
      }else if(direction = 3){ 
       direction = 2; 
      }else{ 
       direction = 1; 
      } 
     } else if (itemHead == 3) { 
      if(direction == 1){ 
       direction = 4; 
      }else if(direction == 2){ 
       direction = 3; 
      }else if(direction = 3){ 
       direction = 1; 
      }else{ 
       direction = 2; 
      } 
     } 
    } 
    printf("%d %d %d", snakeLength, tableSnake[0][0], tableSnake[0][1]); 

    return (EXIT_SUCCESS); 
} 

void moveSnake(int *snakeLength,int direction, int **tableSnake, int extend){ 
    int tempX = tableSnake[0][0]; 
    int tempY = tableSnake[0][1]; 
    int tempDirection = tableSnake[0][2]; 

    int tempXTail = tableSnake[*snakeLength -1][0]; 
    int tempYTail = tableSnake[*snakeLength -1][1]; 
    int tempDirectionTail = tableSnake[*snakeLength -1][2]; 

    int tempRep[3] = {tempXTail,tempYTail,tempDirectionTail}; 
    if(direction == 1){ 
     tempY++; 
    }else if(direction == 2){ 
     tempY--; 
    }else if(direction == 3){ 
     tempX--; 
    }else if(direction == 4){ 
     tempX++; 
    } 

    int *temp; 
    temp = malloc(3 * sizeof(int)); 
    for(int i = 0; i < *snakeLength; i++){ 
     temp = tableSnake[i]; 
     tableSnake[i][0] = tempX; 
     tableSnake[i][1] = tempY; 
     tableSnake[i][2] = tempDirection; 
     tempX = temp[0]; 
     tempY = temp[1]; 
     tempDirection = temp[2]; 
    } 
    if(extend == 1){ 
     // this is where the error occurs 
     *snakeLength = *snakeLength +1; 
     tableSnake = realloc(tableSnake, *snakeLength * sizeof(int)); 
     tableSnake[*snakeLength-1] = tempRep; 
    } 

} 

int checkItems(int **tableSnake, int **items, int itemsSize){ 
    int *item; 
    item = malloc(3 * sizeof(int)); 
    int itemX; 
    int itemY; 
    int headX = tableSnake[0][0]; 
    int headY = tableSnake[0][1]; 

    for(int i = 0; i < itemsSize; i++){ 
     item = items[i]; 
     itemX = item[0]; 
     itemY = item[1]; 
     if(itemX == headX && itemY == headY){ 
      return item[2]; 
     } 
    } 
    return -1; 
} 

int selfdestruct(int **tableSnake){ 
    int tempX = tableSnake[0][0]; 
    int tempY = tableSnake[0][1]; 
    int lengthTable = sizeof(tableSnake)/sizeof(tableSnake[0]); 

    for(int i = 1; i < lengthTable; i++){ 
     if(tempX == tableSnake[i][0]){ 
      if(tempY == tableSnake[i][1]){ 
       return 1; 
      } 
     } 
    } 
    return 0; 
} 
+0

あなたはいくつかのメモリリークを持っています: 'item = malloc(3 * sizeof(int));' –

+0

その他の問題: 'temp = malloc(3 * sizeof(int)); for(int i = 0; i <* snakeLength; i ++){ temp = tableSnake [i]; tableSnake [i] [0] = tempX; tableSnake [i] [1] = tempY; tableSnake [i] [2] = tempDirection; tempX = temp [0]; tempY = temp [1]; tempDirection = temp [2]; } '' temp'の内容は、最初にグローバルに初期化されません。 –

+0

@JohnnyMoppそれは単純な解決策になりますが、私の宿題の指針では、競技場は2.000.000x2.000.000のサイズでなければならず、メモリに収まりきらない – Muzgar15

答えて

0

私はこれらの2つの行をまとめると、1つの問題は明らかでしょうか?

tableSnake = (int **) calloc(1,1 * sizeof (int *)); 

...

tableSnake = realloc(tableSnake, *snakeLength * sizeof(int)); 

、その後、あなたは

tableSnake[*snakeLength-1] = tempRep; 

...新しいtableSnake要素のためにメモリを割り当てるが、その代わりに、ローカル変数でそれを指していません。その機能を終了すると自動的に解放されます。

0

の効果:

tableSnake = realloc(tableSnake, *snakeLength * sizeof(int)); 

..doesはmoveSnake()関数の外に伝播しません。一つの修正は、結果、あなたがより明確にVARSを命名していた場合、この問題はおそらく生じないだろう

int ** moveSnake(int *snakeLength,int direction, int **tableSnake, int extend){ 
     ... 
     return tablesnake; 
    ); 

... 

tableSnake=moveSnake(&snakeLength,direction,tableSnake,extend); 

、例えば「localSnake」パラメータ用として「tableSnake」を返すことです。複数のvarに同じ名前を与えないように非常に努力してください:)

関連する問題