charsteer丶 发表于 2016-6-19 20:53:18

程序崩溃的问题

这是之前看的一位鱼油发的代码,程序的内容是一个贪吃蛇。我稍微改了一下发现运行一段时间后会崩溃掉。原因可能是创建食物的时候有一个递归程序,我将这个递归换成迭代之后程序就不会有问题,但是我想知道这个递归是怎么出问题的。请大神们帮我看看,谢谢大家!



#include<stdio.h>
#include<windows.h>
#include<time.h>

#define MAP_LENGTH 78                //定义地图的长度
#define MAP_HIGHT 24                        //定义地图的宽度
#define UP                0
#define DOWN 1
#define LEFT 2
#define RIGHT 3

void Pos(int x, int y);
void CreatMap();
void InitSnake();
void CreatFood();
void BiteSelf();
void CantCrossWall();
void RunSnake();
void EndGame();
void ControlSnake();

typedef structsnake
{
        int x;
        int y;
        struct snake *next;
}snake;

snake *head;                //定义一个蛇头
snake *food;                //用于记录食物
snake *p;                        //用于遍历蛇的指针
int endstatus = 0;                //结束游戏的原因
int run_status = DOWN;                //用于记录运动方向

int main()
{
        CreatMap();
        InitSnake();
        CreatFood();

        while (1)
        {
                ControlSnake();
                BiteSelf();
                CantCrossWall();
                EndGame();
                if (endstatus)
                        break;
        }
        return 0;
}

void Pos(int x, int y)    //定位光标位置
{
        COORD pos;
        pos.X = x;
        pos.Y = y;
        HANDLE
                hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(hOutput, pos);
}

void CreatMap()//创建地图
{
        int i;
        for (i = 0; i < MAP_LENGTH; i += 2)   //创建地图顶横行
        {
                Pos(i, 0);
                printf("口");
        }
        for (i = 0; i < MAP_LENGTH; i += 2)//创建地图底横行
        {
                Pos(i, MAP_HIGHT);
                printf("口");
        }

        for (i = 0; i < MAP_HIGHT; i++)//创建地图左竖行
        {
                Pos(0, i);
                printf("口");
        }
        for (i = 0; i < MAP_HIGHT; i++)//创建地图右竖行
        {
                Pos(MAP_LENGTH, i);
                printf("口");
        }
}

void InitSnake()//初始化蛇
{
        int i;

        snake *tail = (snake*)malloc(sizeof(snake));//定义蛇的初始位置
        tail->next = NULL;
        tail->x = 24;
        tail->y = 5;

        for (i = 0; i < 5; i++)                //用头插法插入蛇的身体
        {
                head = (snake*)malloc(sizeof(snake));
                head->next = tail;
                head->x = 24 + 2 * i;
                head->y = 5;
                Pos(head->x, head->y);
                printf("口");
                tail = head;
        }
}

void CreatFood()                //创建食物
{
        srand(GetTickCount());                //随机创建一个食物
        static snake *food_1 = NULL;

        food_1 = (snake*)malloc(sizeof(snake));

        do
        {
                food_1->x = rand() %( MAP_LENGTH-1)+1;

        } while ((food_1->x) % 2 != 0);                //与蛇头对齐

        food_1->y = rand() % (MAP_HIGHT-1)+1;

        for (p = head; p; p = p->next)                //判断创建的食物是否在蛇身上
        {
                if (food_1->x == p->x && food_1->y == p->y)
                {
                        free(food_1);       
                        CreatFood();
                }
        }

        food = food_1;
        Pos(food_1->x, food_1->y);            //打印出食物
        printf("口");
}

void BiteSelf()                //判断是否咬到自己
{
        for (p = head->next; p; p = p->next)
        {
                if (p->x == head->x && p->y == head->y)
                        endstatus = 1;
        }
}

void CantCrossWall()                //判断会不会撞到墙
{
        if (head->x == 0 || head->x == MAP_LENGTH)
                endstatus = 2;
        if (head->y == 0 || head->y == MAP_HIGHT)
                endstatus = 2;
}

void RunSnake()                //控制蛇的运动
{
        snake *nexthead = (snake*)malloc(sizeof(snake));
                switch (run_status)
        {
                case UP:                //控制蛇向上前进
                        nexthead->y = head->y - 1;
                        nexthead->x = head->x;
                        if (food->x == nexthead->x && food->y == nexthead->y)                //如果碰到了食物
                        {
                                nexthead->next = head;
                                head = nexthead;
                                Pos(head->x, head->y);
                                printf("口");
                                free(food);
                                CreatFood();
                        }
                        else                                        //如果没碰到食物
                        {
                                nexthead->next = head;
                                head = nexthead;
                                for (p = head; p->next->next != NULL; p = p->next)
                                {
                                        Pos(p->x, p->y);
                                        printf("口");
                                }
                                Pos(p->next->x, p->next->y);
                                printf(" ");
                                free(p->next);
                                p->next = NULL;
                        }
                        break;
                case DOWN://控制蛇向下前进
                        nexthead->y = head->y + 1;
                        nexthead->x = head->x;
                        if (food->x == nexthead->x && food->y == nexthead->y)                //如果碰到了食物
                        {
                                nexthead->next = head;
                                head = nexthead;
                                Pos(head->x, head->y);
                                printf("口");
                                free(food);
                                CreatFood();
                        }
                        else                        //如果没碰到食物
                        {
                                nexthead->next = head;
                                head = nexthead;
                                for (p = head; p->next->next != NULL; p = p->next)
                                {
                                        Pos(p->x, p->y);
                                        printf("口");
                                }
                                Pos(p->next->x, p->next->y);
                                printf(" ");
                                free(p->next);
                                p->next = NULL;
                        }
                        break;
                case LEFT:                //控制蛇向左前进
                        nexthead->x = head->x - 2;
                        nexthead->y = head->y;
                        if (food->x == nexthead->x && food->y == nexthead->y)                //如果碰到了食物
                        {
                                nexthead->next = head;
                                head = nexthead;
                                Pos(head->x, head->y);
                                printf("口");
                                free(food);
                                CreatFood();
                        }
                        else                                //如果没碰到食物
                        {
                                nexthead->next = head;
                                head = nexthead;
                                for (p = head; p->next->next != NULL; p = p->next)
                                {
                                        Pos(p->x, p->y);
                                        printf("口");
                                }
                                Pos(p->next->x, p->next->y);
                                printf(" ");
                                free(p->next);
                                p->next = NULL;
                        }
                        break;
                case RIGHT:                                //控制蛇向右前进
                        nexthead->x = head->x + 2;
                        nexthead->y = head->y;
                        if (food->x == nexthead->x && food->y == nexthead->y)                //如果碰到了食物
                        {
                                nexthead->next = head;
                                head = nexthead;
                                Pos(head->x, head->y);
                                printf("口");
                                free(food);
                                CreatFood();
                        }
                        else                                        //如果没碰到食物
                        {
                                nexthead->next = head;
                                head = nexthead;
                                for (p = head; p->next->next != NULL; p = p->next)
                                {
                                        Pos(p->x, p->y);
                                        printf("口");
                                }
                                Pos(p->next->x, p->next->y);
                                printf(" ");
                                free(p->next);
                                p->next = NULL;
                        }
                        break;
                default:
                        break;
        }
}

void ControlSnake()    //按键判断蛇前进方向
{
        if (GetAsyncKeyState(VK_UP) && run_status != DOWN)
                run_status = UP;
        else if (GetAsyncKeyState(VK_DOWN) && run_status != UP)
                run_status = DOWN;
        else if (GetAsyncKeyState(VK_LEFT) && run_status != RIGHT)
                run_status = LEFT;
        else if (GetAsyncKeyState(VK_RIGHT) && run_status != LEFT)
                run_status = RIGHT;
        Sleep(300);
        RunSnake();
}

void EndGame()                //游戏结束判断
{
        switch (endstatus)
        {
        case 1:
                printf("你咬到自己啦!游戏结束");
                break;
        case 2:
                printf("你撞到墙啦!游戏结束");
                break;
        default:
                break;
        }
}

Mikel 发表于 2016-6-20 17:47:03

      srand(GetTickCount());                //随机创建一个食物
      static snake *food_1 = NULL;

      food_1 = (snake*)malloc(sizeof(snake));
个人觉得可能是static引起的内存泄漏。因为递归回来的时候,static已经被更改了。

Mikel 发表于 2016-6-20 17:50:31

本帖最后由 Mikel 于 2016-6-20 17:51 编辑

#include <iostream>

void ddd(int arg) {

    static int i = arg;
    if (arg == 0)
      return ;
    else
      i = arg;
    ddd(arg-1);
    std::cout << i << std::endl;
}

int main()
{
    ddd(2);
    return 0;
}


测试下就知道了

无符号整形 发表于 2016-6-20 19:13:04

Mikel 发表于 2016-6-20 17:50
#include

void ddd(int arg) {


有道理,不断去改static的

charsteer丶 发表于 2016-6-20 22:43:49

Mikel 发表于 2016-6-20 17:50
#include

void ddd(int arg) {


递归能返回说明创建的食物已经符合条件,那么接下来返回只是做与最内层相同的判断,肯定是能满足条件的,不知道我这样理解对不对,请大神指点一下
页: [1]
查看完整版本: 程序崩溃的问题