C:链表推送段错误

时间:2015-05-20 16:29:16

标签: c

我正在尝试编写一个可以在链表末尾添加新结构的函数。虽然它总是有分段错误。

void
push(stk_t *stklist, info_t *gds)
{
    stk_t *current = stklist;

    if (current == NULL)
    {
        current->gds = (info_t *)malloc(sizeof(info_t));
        current->gds = gds;
        current->next = (stk_t *)malloc(sizeof(stk_t));
        current->next = NULL;
    }
    else
    {
        while (current != NULL)
        {
            current = current->next;
        }
        current->next = (stk_t *)malloc(sizeof(stk_t));
        current->next->gds = (info_t *)malloc(sizeof(info_t));
        current->next->gds = gds;
        current->next->next = (stk_t *)malloc(sizeof(stk_t));
        current->next->next = NULL;
    }

}

我的结构

typedef struct{
    char name[NAME_SIZE];
    char aisle;
    int shelf;
    int weight;
    int price;
    int quantity;
} info_t;


typedef struct stk stk_t;

struct stk{
    info_t *gds;
    stk_t *next;
};

函数push()的目的是将第二个参数添加到链表的末尾。

1 个答案:

答案 0 :(得分:2)

您的push()代码非常错误。

分配

gds并立即覆盖:

    current->gds = (info_t *)malloc(sizeof(info_t));
    current->gds = gds;

即使currentNULL,也会立即取消引用(最有可能导致分段错误):

if (current == NULL)
{
    current->gds = (info_t *)malloc(sizeof(info_t));

另外,请勿明确转换malloc的结果。

如果我理解你要做的事情,那么推送应该是这样的。

void
push(stk_t **stklist, info_t *gds)
{
    stk_t* current = *stklist;

    // Create & initialize new entry
    // gds is passed as parameter, so use it!
    stk_t* newstk = malloc(sizeof(stk_t));
    newstk->gds = gds;
    newstk->next = NULL;

    // No entries had been inserted, overwrite root pointer
    if(current == NULL) {
        *stklist = newstk;
        return;
    }

    // Find last entry that has available ->next
    while(current->next != NULL)
        current = current->next;

    current->next = newstk;
}

...

// Use it like this
stk_t* root = NULL;
push(&root, ...);
push(&root, ...);
push(&root, ...);

这非常惯用 - 保持指向第一个条目的指针,并且对于第一个条目覆盖指针本身,后者转到最后一个条目并覆盖其中的next。顺便说一句,这不是堆栈,而是简单的单链表

对于堆栈实现将如下所示:

void
push(stk_t **stklist, info_t *gds)
{
    stk_t* newstk = malloc(sizeof(stk_t));
    newstk->gds = gds;
    newstk->next = *stklist;

    // Push new entry on top of the stack
    *stklist = newstk;
}

info_t*
pop(stk_t **stklist) {
    stk_t* current = *stklist;
    info_t* gds;

    if(!current)
        return NULL;

    // Remove entry from top of the stack and
    // use next entry as new top
    *stklist = current->next;
    gds = current->gds;
    free(current);

    return gds;
}