这需要释放node中 position 分配的内存么(注释地方);
我 如果释放position 就会报错
有大佬知道么
更新;->
出链表的时候释放没报错
当最后程序结束是清空释放 position 报错
我认为position位置应该是有效的,程序其他地方也没去变动position地址
代码片段(代码主要是github大佬的代码,https://github.com/mnisjk/snake.git)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <curses.h>
#include <sys/select.h>
#include <time.h>
#define SRC_WIDTH 70
#define SRC_HEIGHT 20
WINDOW *g_mainwin;
int g_oldcur, g_score = 0, g_width, g_height;
typedef struct
{
int x;
int y;
} pos;
pos fruit;
bool *spaces;
// queue stuff
struct s_node
{
pos *position;
struct s_node *prev;
struct s_node *next;
} *front = NULL,*back =NULL;
typedef struct s_node node;
pos * peek(){
return front == NULL ? NULL : front->position;
}
node * dequeue(){
node *oldfront = front;
front = front->next;
return oldfront;
}
//queue a position at the back
void enqueue(pos position)
{
pos *newpos = (pos *)malloc(sizeof(position));
node *newnode = (node *)malloc(sizeof(node));
newpos->x = position.x;
newpos->y = position.y;
newnode->position = newpos;
if(front == NULL && back ==NULL)
front = back = newnode;
else
{
back->next = newnode;
newnode->prev = back;
back = newnode;
}
}
//end queue stuff
//start snake stuff
void snake_write_text(int y,int x,char *str)
{
mvwaddstr(g_mainwin, y, x, str);
}
//draw the borders
void snake_draw_board()
{
int i;
for (i = 0; i < g_height;i++){
snake_write_text(i, 0, "|");
snake_write_text(i, g_width - 1, "|");
}
for (i = 0; i < g_width;i++)
{
snake_write_text(0, i, "-");
snake_write_text(g_height, i, "-");
}
snake_write_text(g_height + 1, 2, "Score:");
}
//resets the terminal window and clears up the mem
void snake_game_over(int i,pos p)
{
free(spaces);
while (front)
{
node *n = front;
front = front->next;
free(n->position);
free(n);
}
endwin();
printf("%d\n", i);
printf("%d,%d\n",p.x,p.y);
exit(0);
}
//当前位置是否在界限里面
bool snake_in_bounds(pos position)
{
return position.y < g_height && position.y > 0 && position.x < g_width - 1 && position.x > 0;
}
//2d坐标映射1d
int snake_cooridinate_to_index(pos position)
{
return g_width * position.y + position.x;
}
//1d映射对应的坐标
pos snake_index_to_coordinate(int index)
{
int x = index % g_width;
int y = index / g_width;
return (pos){x, y};
}
//随机出现水果
void snake_draw_fruit()
{
attrset(COLOR_PAIR(3));
int idx;
do{
idx = rand() % (g_width * g_height);
fruit = snake_index_to_coordinate(idx);
} while (spaces[idx] || !snake_in_bounds(fruit));
attron(A_REVERSE);
snake_write_text(fruit.y, fruit.x, " ");
attroff(A_REVERSE);
}
//handles moving the snake for each iteration
bool snake_move_player(pos head)
{
attrset(COLOR_PAIR(1));
//check if we ran into ourself
int idx = snake_cooridinate_to_index(head);
if(spaces[idx]){
pos te = {2, 2};
snake_game_over(2,te);
}
spaces[idx] = true;
enqueue(head);
//check if we're eating the fruit
if(head.x == fruit.x && head.y == fruit.y)
{
snake_draw_fruit();
g_score += 10;
}else{
node *tail = dequeue();
pos tem = *(tail->position);
spaces[snake_cooridinate_to_index(tem)] = false;
snake_write_text(tem.y, tem.x, " ");
//if(tail->position != NULL)
free(tail->position);
free(tail);
tail = NULL;
}
attron(A_REVERSE);
snake_write_text(head.y, head.x, " ");
attroff(A_REVERSE);
char buffer[25];
sprintf(buffer, "%d", g_score);
attrset(COLOR_PAIR(2));
snake_write_text(g_height+1,9,buffer);
}
void check_move_pos(pos *t_head,pos *head){
pos temp;
node t_node = *back;
if (&t_node == NULL)
return ;
else
{
if(t_node.prev != NULL){
if((t_node.prev)->position != NULL){
temp = *((t_node.prev)->position);
if(t_head->x == head->x){ //x方向
if(temp.x == head->x && temp.y == head->y){
if(t_head->y > temp.y)
head->y += 2;
else
head->y -= 2;
}
}else if(t_head->y == head->y) { //y方向
if(temp.x == head->x && temp.y == head->y){
if(t_head->x > temp.x)
head->x += 2;
else
head->x -= 2;
}
}
}
}
}
}
int main(int argc,char *argv[])
{
int key = KEY_RIGHT;
if((g_mainwin = initscr()) == NULL)
{
perror("error initialising ncursess");
exit(EXIT_FAILURE);
}
srand(time(NULL));
noecho();
curs_set(2);
halfdelay(1);
keypad(g_mainwin, TRUE);
g_oldcur = curs_set(0);
start_color( );
init_pair( 1, COLOR_RED, COLOR_BLACK );
init_pair( 2, COLOR_GREEN, COLOR_BLACK );
init_pair( 3, COLOR_YELLOW, COLOR_BLACK );
init_pair( 4, COLOR_BLUE, COLOR_BLACK );
init_pair( 5, COLOR_CYAN, COLOR_BLACK );
init_pair( 6, COLOR_MAGENTA, COLOR_BLACK );
init_pair( 7, COLOR_WHITE, COLOR_BLACK );
getmaxyx( g_mainwin, g_height, g_width );
g_width = g_width < SRC_WIDTH ? g_width : SRC_WIDTH;
g_height = g_height < SRC_HEIGHT ? g_height : SRC_HEIGHT;
// Set up the 2D array of all spaces
spaces = (bool*) malloc( sizeof( bool ) * g_height * g_width );
snake_draw_board( );
snake_draw_fruit( );
pos head = { 5,5 };
enqueue( head );
// Event loop
while( 1 )
{
pos t_head = head;
int in = getch();
if( in != ERR )
key = in;
switch (key)
{
case KEY_DOWN:
case 'k':
case 'K':
head.y++;
break;
case KEY_RIGHT:
case 'l':
case 'L':
head.x++;
break;
case KEY_UP:
case 'j':
case 'J':
head.y--;
break;
case KEY_LEFT:
case 'h':
case 'H':
head.x--;
break;
}
//禁止反向
check_move_pos(&t_head, &head);
if (!snake_in_bounds(head))
snake_game_over(3, head);
else
snake_move_player(head);
}
pos te = {4, 4};
snake_game_over(4,te);
}
调试了 越来混乱了,一运行蛇啥不吃,链表里面应该只有一个地址才对,出链表也对应的释放了地址.可调试出现了最后出现了3个
更新->
搞好了,
新建节点 node *newnode = (node *)malloc(sizeof(node));时候,莫名
newnode 中 next 指针指向了未知 地址,按原本意思应该指向 0x0空地址
所有 newnode->next = newnode->prev = NULL; 初始化一下,不然结束的释放链表 就会找到这个 0x20 的地址
一切正常了 ,高兴