2017-03-24 6 views
-1

Ich versuche, eine C-Version des Spiels Snake für meine Hausaufgabe zu machen. Ich habe alle notwendigen mechainsms in das Spiel implementiert, aber ich habe ein Problem mit der dynamischen Speicherzuweisung. Meine 'Schlange' wird in einem Array als eine Liste von Körperteilen und deren Position gespeichert. Wenn die Schlange die Frucht frisst, versuche ich, die Länge der Schlange zu ändern und ein weiteres Körperteil zum Array hinzuzufügen. Da ich die endgültige Größe der Schlange nicht im Voraus kenne, versuche ich das Array mit realloc zu verlängern. Unten ist mein Code. Hinweis: Es funktioniert für 14 Iterationen, bevor ein SIGABRT verursacht wird.SIGABRT bei der Verwendung von Realloc()

#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

Sie haben einige Speicherlecks: 'item = malloc (3 * sizeof (int));' –

+0

andere Ausgabe: 'temp = malloc (3 * sizeof (int)); für (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]; } 'Inhalt von' temp' ist beim ersten Mal global nicht initialisiert. –

+0

@JohnnyMopp Das wäre die einfache Lösung, aber meine Hausaufgabenanweisungen besagen, dass das Spielfeld die Größe 2.000.000x2.000.000 haben sollte, was viel zu groß ist, um in den Speicher zu passen – Muzgar15

Antwort

0

Wenn ich diese zwei Zeilen zusammenlege, sollte ein Problem offensichtlich sein?

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

...

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

und dann sind Sie nicht Speicher für das neue tableSnake Element Zuteilung, sondern es bei einer lokalen Variablen zeigen ...

tableSnake[*snakeLength-1] = tempRep; 

. ..die automatisch freigegeben werden, wenn Sie diese Funktion beenden.

0

die Wirkung:

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

..does nicht außerhalb des moveSnake() Funktion propagieren. Eine Lösung ist, zurückzukehren ‚tableSnake‘ als Ergebnis

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

... 

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

Dieses Problem würde wahrscheinlich nicht einmal entstanden, wenn Sie die Vars deutlicher genannt hatte, zB ‚localSnake‘ für den Parameter. Versuchen Sie sehr, nicht mehr als eine var den gleichen Namen zu geben :)

Verwandte Themen