Почему код моего связанного списка приводит к ошибке сегментации? - PullRequest
1 голос
/ 02 марта 2011

Я написал быстрый общий список ссылок, простые вещи.Но у меня есть ошибка, и я не могу определить, на что она жалуется.Соответствующий код:

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 передается memcmp().Есть идеи?Кроме того, я получил segfault, пытаясь сделать int x = *(int *)n->data, но это мне кажется правильным, не так ли?

Ответы [ 6 ]

1 голос
/ 02 марта 2011

В этом коде:

n->data = data[i];

В настоящее время вы устанавливаете указатель void* data на data[i], но вы действительно хотите установить для него адрес data[i], поэтому вам нужно сделать:

n->data = &data[i];

По этой же причине у вас есть сегфоут на касте.

0 голосов
/ 02 марта 2011

Вы присваиваете переменную int

n->data = data[i];

То, что должно быть указателем

typedef struct _node {
void *data;
struct _node *next;
} node;
0 голосов
/ 02 марта 2011

Кроме того, вызов memcmp в find_node иногда сравнивает слишком много данных. Вы используете memcmp с размером данных, которые вы ищете. Если данные в текущем узле короче этого, memcmp выйдет за его пределы на запрещенную территорию. (Тестовый код, который вы опубликовали, обычно не сработает, потому что большинство полей данных имеют одинаковую длину.) Вам необходимо добавить поле длины для каждого узла и использовать минимум обеих длин в memcmp.

0 голосов
/ 02 марта 2011

Похоже, вы не согласны с тем, является ли ваш data указателем или указателем, который приведен к int. Вы передаете int (поскольку указатель является в основном int причиной приведения).

memcpy естественно хочет void *, а не int.

Таким образом, решение действительно состоит в том, чтобы передать указатель на ваши int в данных и заставить все остальное работать с этим.

0 голосов
/ 02 марта 2011

Предполагая, что ваши функции выделения памяти работают, скорее всего, n-> data равен NULL, и поэтому вы не можете получить к нему доступ.Кроме того, почему вы передаете массив данных как & data [10]?Почему бы просто не использовать данные, поскольку идентификатор массива является указателем на его первое местоположение?

0 голосов
/ 02 марта 2011

Segmentation Fault происходит, когда вы пытаетесь разыменовать нулевой указатель.Если вы знаете строку, где это происходит, убедитесь, что там нет NULL, например int x = *(int *)n->data сгенерирует SEGFAULT, если n равно NULL или n->data равно NULL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...