私は宿題のために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;
}
あなたはいくつかのメモリリークを持っています: 'item = malloc(3 * sizeof(int));' –
その他の問題: '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'の内容は、最初にグローバルに初期化されません。 –
@JohnnyMoppそれは単純な解決策になりますが、私の宿題の指針では、競技場は2.000.000x2.000.000のサイズでなければならず、メモリに収まりきらない – Muzgar15