鱼C论坛

 找回密码
 立即注册
查看: 1838|回复: 4

程序崩溃的问题

[复制链接]
发表于 2016-6-19 20:53:18 | 显示全部楼层 |阅读模式
20鱼币
这是之前看的一位鱼油发的代码,程序的内容是一个贪吃蛇。我稍微改了一下发现运行一段时间后会崩溃掉。原因可能是创建食物的时候有一个递归程序,我将这个递归换成迭代之后程序就不会有问题,但是我想知道这个递归是怎么出问题的。请大神们帮我看看,谢谢大家!



#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 struct  snake
{
        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;
        }
}

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-6-20 17:47:03 | 显示全部楼层
        srand(GetTickCount());                //随机创建一个食物
        static snake *food_1 = NULL;

        food_1 = (snake*)malloc(sizeof(snake));
个人觉得可能是static引起的内存泄漏。因为递归回来的时候,static已经被更改了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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;
}


测试下就知道了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-6-20 19:13:04 | 显示全部楼层
Mikel 发表于 2016-6-20 17:50
#include

void ddd(int arg) {

有道理,不断去改static的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-6-20 22:43:49 | 显示全部楼层
Mikel 发表于 2016-6-20 17:50
#include

void ddd(int arg) {

递归能返回说明创建的食物已经符合条件,那么接下来返回只是做与最内层相同的判断,肯定是能满足条件的,不知道我这样理解对不对,请大神指点一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-27 04:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表