【问题标题】:C undefined behavior - Singly Linked ListC 未定义行为 - 单链表
【发布时间】:2016-01-23 00:05:58
【问题描述】:

我已经实现了一个单链表,我注意到非常奇怪的行为,但无法确定它发生的确切原因。我尝试使用gdb 来找出问题所在,每当我计算列表的大小时,它看起来就是事情开始出错的时候。这是我用来测试我的实现的程序,下面是实际的实现。

#include <stdio.h>
#include "singlylinked.h"

slist initialize(void); /* initializes test singly linked list */

slist initialize(){
    int i, a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    slist l = sl_alloc();
    int a_size = sizeof(a)/sizeof(a[0]);
    for(i=0;i<a_size;i++){
        sl_add(l, (void *)&a[i]);
    }
    return l;
}

int main(){
    slist l = initialize();
    int i, size = sl_size(l);
    for(i = 0; i < size; i++){
        printf("%d ", *(int *)sl_get(l,i));
    }
    fputc('\n',stdout);
    return 0;
}

现在是实际的实现,我只贴出测试中用到的方法:

/* allocates an empty slist */
slist sl_alloc(){
    return (slist) calloc(1, sizeof(struct node));
}

/* adds val to linked list */
void sl_add(slist l, void *val){
    node *current, *new;
    new = calloc(1, sizeof(struct node));
    new->content = val;
    new->next = NULL;
    if((current = *l)){
        while(current->next){
            current = current->next;
        }
        current->next = new;
    } else {
        *l = new;
    }
}

/* returns ith value in singly linked list l */
void *sl_get(slist l, int i){
    node *current;
    int j; /* counter */
    void *result = NULL;
    if((current = *l)){
        int size = sl_size(l);
        if(i < size){
            for(j = i; j > 0; j--){
                current = current->next;
            }
            result = current->content;
        } 
    }
    return result;
}

/* returns the size of the singly linked list */
int sl_size(slist l){
    int size = 0;
    node *current;
    if((current = *l)){
        do {
            size++;
            current = current->next;
        } while (current);
    }
    return size;
}

现在这就是我定义sliststruct node 的方式:

typedef struct node **slist;

typedef struct node {
    void *content;
    struct node *next;
} node;

编辑:奇怪的行为是这样的:当我尝试打印内容时,它会打印出列表中的错误值。当我使用gdb 运行程序时,这在第一次调用sl_size 后开始发生。

【问题讨论】:

  • 这是什么行为?会发生什么,您预计会发生什么?
  • 您能否说明一下这种“奇怪的行为”实际上是什么?示例输出(错误消息)会很好。
  • 好吧,一方面,slist 不是指向struct node 的指针,而是指向指向struct node 的指针。您对calloc 的调用分配了错误的大小(它分配的是struct node,而不是指向一个的指针)。
  • 只是为了澄清而编辑。

标签: c gdb singly-linked-list


【解决方案1】:

问题是您对列表的初始化。

您将数组a[] 的10 个元素添加到您在initialize() 中创建的列表中。唯一的问题是您在列表节点中存储指向数组 a[] 中数据的指针。不幸的是,这个数组是函数的本地数组!一旦你从initialize() 返回,这个数组就不再有效,并且指针不再指向有效的地方。因此,您希望指向的数字将被“垃圾”值替换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-01
    • 2017-11-24
    • 2022-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    相关资源
    最近更新 更多