为什么我的链表代码会导致分段错误?

时间:2011-03-02 11:35:36

标签: c list

我写了一个快速的通用链表,简单的东西。但我有一个错误,我无法发现它抱怨的是什么。相关代码:

typedef struct _node {
    void *data;
    struct _node *next;
} node;

typedef struct _queue {
    node *root;
    node *last;
    unsigned int length;
} queue;

node * find_node(void *data, int size, queue *q)
{
    node *n;

    for(n=q->root;n;n=n->next)
        if(memcmp(data, n->data, size)==0)
            return (n);

    return (NULL);
}

测试它:

queue q = {NULL, NULL, 0};
node *n;
int data[QUEUEMAX];
int i;

/* insert bunch of ints into queue */
for(i=0;i<QUEUEMAX;i++) {
    data[i] = give_me_a_number();
    n = alloc_node();
    n->data = data[i];
    insert_into(n, &q);
}

printf("list size = %d.\n", q.length);

/* print out, make sure they're there */   
for(n=q.root;n;n=n->next)
    printf("data = %d\n", (int)n->data); //*(int *)n->data didn't work, segfault?

/* find a specific node */
node *nd = find_node(&data[10], sizeof(int), &q);
/* remove it */
rm_node(nd, &q);

运行它:

$ ./test
list size = 256.
data = 10
data = 11
data = 12
data = 13
data = 14
data = 15
data = 16
... blah blah (256 lines)
Segmentation Fault

gdb说问题是memcmp()中的find_node()。我认为gcc抱怨传递给n->data的{​​{1}}。有任何想法吗?另外,我试图做memcmp()的段错误,但这似乎对我有用,不是吗?

6 个答案:

答案 0 :(得分:1)

在此代码中:

n->data = data[i];

您目前正在将void* data指针设置为data[i],但您确实要将其设置为 data[i]地址,因此您需要执行以下操作:

n->data = &data[i];

这也是你在演员阵容中遇到段错误的原因。

答案 1 :(得分:0)

当您尝试取消引用NULL指针时,会发生

Segmentation Fault。如果您知道发生这种情况的行,请确认其中没有NULL,如果n为int x = *(int *)n->dataSEGFAULT为{{1},示例NULL将生成n->data }}

答案 2 :(得分:0)

假设您的内存分配功能正在运行,很可能n-&gt;数据为NULL,因此您无法访问它。另外,为什么要将数据数组作为&amp; data [10]传递?为什么不直接使用数据,因为数组的标识符是指向其第一个位置的指针?

答案 3 :(得分:0)

看起来你的data是一个指针还是一个指针被转换为int是不一致的。您正在传递int(因为指针基本上是演员的int原因。)

memcpy自然需要void *,而不是int

因此,解决方案实际上是在数据中传递指向int的指针,并使其他所有内容都能正常工作。

答案 4 :(得分:0)

此外,find_node中的memcmp调用有时会比较过多的数据。您正在使用memcmp来查找您正在搜索的数据的大小。如果当前节点中的数据短于此值,则memcmp将超出它,进入禁区。 (您发布的测试代码通常不会触发此错误,因为大多数数据字段具有相同的长度。)您需要为每个节点添加一个长度字段,并在memcmp中使用两个长度的最小值。

答案 5 :(得分:0)

您正在分配一个int变量

n->data = data[i];

它应该是什么指针

typedef struct _node {
void *data;
struct _node *next;
} node;