贪吃蛇原码的疑问:关于new
这是原码的一部分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)
{
GetLocalTime(&st);
srand(st.wMilliseconds);
food->pt.x = rand() % XWIDTH, food->pt.y = rand() % YHEIGHT;
}
GameClient = 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 = 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 = true;
}
else//psLast == &snake,即蛇只有蛇头
GameClient = false;
if(TouchWall())
IsOver = true; //则标记游戏结束
else
GameClient = 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,这会不会造成内存泄露?
本帖最后由 ~风介~ 于 2015-3-2 17:25 编辑
new和delete不都是配套使用的吗?{:5_94:} 《c++ primer plus》第六版里面有强调哦!有空可以看看~{:5_92:}
注意这里的void NewFood(hwnd)是一个函数而不是new Food(hwnd)。 要看仔细哦。 freeparty 发表于 2015-3-3 12:47
注意这里的void NewFood(hwnd)是一个函数而不是new Food(hwnd)。
在这个void NewFood( hwnd ) 函数里会用到 new 来申请内存 。 没释放不是会造成内存泄漏么。 {:1_1:} 感觉会产生内存泄露。但是不一定就直接影响程序运行,如果一直玩下去不终止程序,迟早会因泄露造成异常。
New 开的内存都在堆上是不会因为函数的终止而释放的,因此每调用一次NewFood 函数,就会在heap 里开辟一个struct snake 的内存,周而复始一定会泄露的。 个人认为,产生食物new出来的结构体用的内存,玩一天游戏也不过几兆,所以作者应该忽略了,如果是其他地方,尤其循环里面或者反复调用的new就一定要配对delete,理论上这代码有瑕疵,但是实际上这点泄露应该没什么大问题
页:
[1]