C - ошибка при доступе к элементу структуры с ненулевым указателем - PullRequest
0 голосов
/ 05 марта 2012

Я создал базовый LinkedList на C, и у меня есть создание, добавление и начало работы.Помимо get вызывает segfault после, казалось бы, случайного количества вызовов get (Сбой 96-го вызова, список содержит 94 элемента). При доступе к следующему указателю на текущем узле возникает segfault.

Эта строка вызываетsegfault while(cur->next != null && i < index) Я проверил, и cur не возвращает нулевой адрес памяти до того, как произойдет segfault.Это также приводит к сбою во втором цикле вызова, который приводит к сбою (Второй printf выводит только 0).Это вся функция get

void *linkedList_get(LinkedList list, int index)
{
    Node *cur = list.head;
    int i = 0;
    if(index != 0)
    {
        while(cur->next != null && i < index)
        {
            cur = cur->next;
            printf("I %i\n", i);
            printf("%i\n", cur);
            i++;
        }
    }
    if(index == i)
        return cur->data;
    return null;
}

Это структура Node

typedef struct
{
    void *data;
    struct Node *next;
    struct Node *prev;
} Node;

Это весь код, если необходимо http://pastebin.com/hpWA8tb8 (Обратите внимание, это моя первая программа на Cтак что это, вероятно, немного небрежно, и я не освобождаю память)

Ответы [ 3 ]

1 голос
/ 05 марта 2012

Эдмунд, вероятно, нашел ответ. Но я также поймал это:

Это опасно неправильно, особенно в 64-битных ОС и компиляции, где указатель sizeof больше, чем sizeof (int).

Node *n = malloc(sizeof(int) * 3);

Следует читать:

Node *n = malloc(sizeof(Node));
1 голос
/ 05 марта 2012

Как сказал Эдмунд, в этой программе может быть много ошибок,

Я возражаю против этой части:

next->data = malloc(sizeof(data));
next->data = data;

Он выделяет некоторую память для next-> data, затем НЕМЕДЛЕННО стирает этот указатель и вводит другое значение. Память, безусловно, просочилась, и это может привести к другим последствиям.

1 голос
/ 05 марта 2012

createEmptyNode фактически не возвращает n.Это означает, что указатели на узлы, используемые в связанном списке, на самом деле являются поддельными (и указывают в любом месте памяти).То же самое для многих других ваших функций создания.

Вы должны скомпилировать с включенными предупреждениями, которые, вероятно, поймали бы это.(Например, используя -Wall в GCC).

В общем, если у вас есть какие-либо ошибки памяти в программе на C, вы не можете точно рассуждать о ее поведении после того, как эта ошибка была вызвана.Поэтому я не буду утверждать, что исправление этого заставит это работать.;-) Существует также ошибка, когда вы устанавливаете данные в узле, назначая указатель вместо содержимого указателя (для которого вы должны использовать что-то вроде memmove, передавая размер содержимого явно).

...