在for循环中初始化双向链表会导致崩溃

时间:2016-01-21 22:46:44

标签: c for-loop linked-list crash initialization

我正在使用双向链表编写C中的经典Snake游戏,并编写了一个创建指针的函数,为结构分配所需的空间,然后为列表中的下一个指针分配内存,依此类推。最后,函数返回指向第一个元素的指针,并将其指定给main函数中的头指针。

当开始游戏时,我希望蛇的长度为3,所以我在函数中有三个malloc,并使用指针,指针 - >接下来,指针 - > next-> next等等,一切都是工作

由于在这个过程中需要重复很多步骤,我想把所有这些都放到像这样的for循环中:

#include <stdio.h>
#include <stdlib.h>

typedef struct snake snake;
struct snake {
    int x; /* x coordinate */
    int y; /* y coordinate */
    snake *previous;
    snake *next;
};

snake *initSnake(void) {
    snake *pointer, *tmp1, *tmp2 = NULL;
    /* three iterations, so the snake will have a length of three */
    for( int i = 0; i<3; i++, tmp1 = tmp1->next) {
        if(NULL == (tmp1 = (snake*)malloc(sizeof(snake)))) {
            return NULL;
        }
        /* coordinates */
        tmp1->x = 20;
        tmp1->y = 10 + i;
        /* first previous points to NULL */
        tmp1->previous = tmp2;
        /* temporarily store last pointer to be used for next previous pointer */
        tmp2 = tmp1;
        if(0 == i) {
            /* store first pointer so it can be returned */
            pointer = tmp1;
        }

    }
    /* the last next pointer has to point to NULL */
    tmp1 = NULL;
    /* now return the pointer to the first element in list */
    return pointer;
}


int main() {
    /* pointer to first element in list */
    snake *head = NULL;

    if(NULL == (head = initSnake() ) ) {
        fprintf(stderr, "Not enough memory!\n");
        return EXIT_FAILURE;
    }
    /* here everything works fine */
    printf("%d\n", head->y);
    printf("%d\n", head->previous);
    /* when trying to acces the content of the next element, the program crashes... */
    printf("%d\n", head->next->x);
    /* pause */
    getchar();
}

问题在于,当我尝试访问main函数中列表的第二个元素时,游戏崩溃了。我怀疑是有问题的 for循环中的tmp1 = tmp1->next我并没有真正访问下一个指针,但我不完全确定。

你可以帮帮我吗?

2 个答案:

答案 0 :(得分:1)

你有很多错误表明你并不真正理解记忆,变量和等等。指针工作。例如,在tmp1 = tmp1->next循环结束时执行for,紧接着tmp1 = (snake*)malloc(sizeof(snake))覆盖tmp1并使之前的操作毫无意义。代码中的其他位置也存在类似的操作。

要清理它,试试这个:

snake *initSnake(void) {
    snake *head, **current, *prev;

    /* three iterations, so the snake will have a length of three */
    for(int i = 0, prev = NULL, current = &head; i<3; i++) {
        if(NULL == (*current = malloc(sizeof(snake)))) {
            return NULL; /* note that if this happens midway
                  through allocation, nothing gets freed */
        }
        /* coordinates */
        (*current)->x = 20;
        (*current)->y = 10 + i;
        /* next, previous pointers */
        (*current)->next = NULL;
        (*current)->previous = prev;
        prev = *current;
        current = &current->next;
    }

    /* now return the pointer to the first element in list */
    return head;
}

答案 1 :(得分:0)

您必须将最后一个下一个指针设置为NULL:

/* the last next pointer has to point to NULL */
tmp1->next = NULL;   // -> next !

因为tmp1是一个局部变量,并且在返回之前将其设置为NULL将不起作用。

修改:

Ooops,也不在for循环中执行tmp1 = tmp1->next:因为在您尝试执行此操作时未设置它。您需要与之前一起设置下一个:

   /* first previous points to NULL */
    tmp1->previous = tmp2;
    if (tmp2) 
        tmp2->next = tmp1; 

<强> Online demo