鱼C论坛

 找回密码
 立即注册
查看: 5417|回复: 8

贪吃蛇原码的疑问:关于new

[复制链接]
发表于 2015-3-2 17:11:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这是原码的一部分
struct Snake
{
        Snake():next(NULL), before(NULL)
        {
                pt.x = 0; pt.y = 0;
        }
        Snake(const POINT &npt, Snake *, Snake *);
        POINT        pt;
        Snake * next, * before;
} snake;  //定义蛇头
Snake * psLast = NULL, * food = NULL;
void NewFood(HWND hwnd)
{
        food = new Snake();      原码在这儿用new申请了内存
        SYSTEMTIME st;
        GetLocalTime(&st);
        srand(st.wMilliseconds);
        food->pt.x = rand() % XWIDTH, food->pt.y = rand() % YHEIGHT;
        while(GameClient[food->pt.x][food->pt.y])
        {
                GetLocalTime(&st);
                srand(st.wMilliseconds);
                food->pt.x = rand() % XWIDTH, food->pt.y = rand() % YHEIGHT;
        }
        GameClient[food->pt.x][food->pt.y] = true;
        InvalidateRect(hwnd, NULL, TRUE);
}

//判断前方是否是食物
inline bool IsFood()
{
        if(snake.pt.x == food->pt.x && snake.pt.y == food->pt.y)
                return true;
        else
                return false;
}

//判断是否撞墙或者撞到自己身体
bool TouchWall()
{
        Snake * temp = psLast;
        //超越边界判断
        if(snake.pt.x >= XWIDTH ||
                snake.pt.x < 0 ||
                snake.pt.y < 0 ||
                snake.pt.y >= YHEIGHT)
                return true;
        //碰撞自身身体判断
        while(temp != &snake)
        {
                if(snake.pt.x == temp->pt.x &&
                        snake.pt.y == temp->pt.y)
                        return true;
                temp = temp->before;
        }
        return false;
}
               

void Move(HWND hwnd)
{
        int x, y;  //用于记录蛇头的当前位置(未前进时)
        //标记前方是否为食物,默认为不是食物,表示系通常的前进
        Snake * temp = psLast;
       
        //记录蛇头当前坐标
        x = snake.pt.x;
        y = snake.pt.y;
        //测试前进的地方是否是食物,同时将蛇头前进
        switch(direct)
        {
        case UP:
                --snake.pt.y;
                break;
        case DOWN:
                ++snake.pt.y;
                break;
        case LEFT:
                --snake.pt.x;
                break;
        case RIGHT:
                ++snake.pt.x;
                break;
        default:
                break;
        }
        //如果不是食物,作如下处理
        if(!IsFood())
        {
                //最后一节不是蛇头
                if(temp != &snake)
                {
                        GameClient[temp->pt.x][temp->pt.y] = false;
                        while(temp != snake.next)
                        {
                                temp->pt.x = temp->before->pt.x;
                                temp->pt.y = temp->before->pt.y;
                                temp = temp->before;
                        }
                        temp->pt.x = x;
                        temp->pt.y = y;
                        GameClient[temp->pt.x][temp->pt.y] = true;
                }
                else  //psLast == &snake,即蛇只有蛇头
                        GameClient[x][y] = false;                               
                if(TouchWall())
                        IsOver = true;                                                //则标记游戏结束
                else
                        GameClient[snake.pt.x][snake.pt.y] = true;        //不然移动后的蛇头位置标记为有方块了
                InvalidateRect(hwnd, NULL, TRUE);                //刷新游戏区
        }
        //如果是食物,作如下处理
        else
        {
                ++Score;
                food->before = psLast;       把new申请的内存加入链表中
                psLast->next = food;       
               
                if(temp != &snake)
                {       
                        food->pt.x = psLast->pt.x;
                        food->pt.y = psLast->pt.y;
                        while(temp != snake.next)
                        {
                                temp->pt.x = temp->before->pt.x;
                                temp->pt.y = temp->before->pt.y;
                                temp = temp->before;
                        }
                        //temp=snake.next;
                        temp->pt.x = x;
                        temp->pt.y = y;
                }
                else  //psLast == &snake,即蛇只有蛇头
                {
                        food->pt.x = x; food->pt.y = y;
                }
                psLast = food;     把申请的内存地址赋给别一个指针
                NewFood(hwnd);     刷新食物,又会用到new
        }
}
整个原码过程都不曾出现delete,这会不会造成内存泄露?

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

使用道具 举报

发表于 2015-3-2 17:24:27 | 显示全部楼层
本帖最后由 ~风介~ 于 2015-3-2 17:25 编辑

new和delete不都是配套使用的吗? 《c++ primer plus》第六版里面有强调哦!有空可以看看~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-3 12:47:49 | 显示全部楼层
注意这里的void NewFood(hwnd)是一个函数而不是new Food(hwnd)。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2015-3-3 12:48:06 | 显示全部楼层
要看仔细哦。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-3 12:59:09 | 显示全部楼层
freeparty 发表于 2015-3-3 12:47
注意这里的void NewFood(hwnd)是一个函数而不是new Food(hwnd)。

在这个void NewFood( hwnd ) 函数里会用到 new 来申请内存 。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-3 13:03:21 | 显示全部楼层
没释放不是会造成内存泄漏么。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-4 04:12:28 | 显示全部楼层
{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-3-4 10:59:14 | 显示全部楼层
感觉会产生内存泄露。但是不一定就直接影响程序运行,如果一直玩下去不终止程序,迟早会因泄露造成异常。
New 开的内存都在堆上是不会因为函数的终止而释放的,因此每调用一次NewFood 函数,就会在heap 里开辟一个struct snake 的内存,周而复始一定会泄露的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-5 10:11:47 | 显示全部楼层
个人认为,产生食物new出来的结构体用的内存,玩一天游戏也不过几兆,所以作者应该忽略了,如果是其他地方,尤其循环里面或者反复调用的new就一定要配对delete,理论上这代码有瑕疵,但是实际上这点泄露应该没什么大问题

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +2 收起 理由
拈花小仙 + 3 + 3 + 2 热爱鱼C^_^

查看全部评分

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-25 18:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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