Проблема с указателями в C - PullRequest
1 голос
/ 20 апреля 2011

У меня проблема с моими указателями и структурами в C (я знаю, я знаю, довольно просто!). Я практиковал свою процессуальную парадигму. Это первый раз, когда я использую отладчик, потому что он мне действительно не нужен раньше в моей жизни: <так что я, если вы помогаете мне, я буду благодарен. </p>

Я определил следующую структуру, чтобы составить список:

typedef struct node {
    int info;
    struct node *next;
    struct node *prev;
} node_t;

А затем эта функция, чтобы заполнить его:

void addNodo(node_t * list, int x){
    node_t * pointer;
    node_t * temp;

    temp = (node_t *)malloc(sizeof(node_t));
    temp->info = x;
    temp->next = NULL;
    temp->prev = NULL;

    pointer = list;

    if(pointer == NULL){ //it's empty so start it
        list = temp;
        return;
    }

    if (pointer->info <= x) { //I like my lists tidy so...
        while((pointer->next != NULL) && (pointer->info <= x)){
            pointer = pointer->next;
        }

        if(pointer->next == NULL){
            pointer->next = temp;
            temp->prev = pointer;
            return;
        }

        pointer->next->prev = temp;
        temp->next = pointer->next;
        temp->prev = pointer;
        pointer->next = temp;
        return;
    }
}

И затем, делая это:

int main(int argc, char** argv) {
    node_t * list = NULL;
    addNodo(list, 1);
    printf("x: %d", list->info);
    return (EXIT_SUCCESS);
}

Это вызывает у меня ошибку сегментации! Когда я отлаживаю его, все весело и игры, пока он не пройдет строку ++++, список адресов возвращается к 0x0 и не может заставить его работать. Я знаю, что где-то есть ошибка, но, насколько мне известно, это совершенно нормально. Пожалуйста, найдите мою ошибку и научите меня некоторым указателям.

Ответы [ 4 ]

4 голосов
/ 20 апреля 2011

Когда вы звоните addNode(), вы передаете указатель по значению .Поэтому, когда вы изменяете его в теле функции, изменение теряется и не распространяется за пределы функции.Вам нужно объявить его как:

void addNode(node_t **pointer, int x)

и затем использовать *pointer в функции.

И когда вы вызываете ity в main, передайте в &list

1 голос
/ 20 апреля 2011

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

Что вы должны делать во время вызова, это:

    addNodo(&list, 1);

В функции внесите следующие изменения:

void addNodo(node_t ** list, int x)
/* This will enable you to get a copy of the address of the list variable.
   Please note that this is also pass by value, C does not support pass by
   reference */

Затем внесите это изменение:

    pointer = *list;
    /* this will make the pointer point to the beginning of list as now
       list is a pointer to pointer type */

Надеюсь, это поможет вам.

Кстати, пожалуйста, пройдите стандартную книгу по Си (я рекомендую K & R), чтобы ознакомиться с передачей аргументов в Си и что происходитвнутри.

1 голос
/ 20 апреля 2011

Проблема в том, что вы не можете изменить список внутри функции addNodo.В Си параметры отправляются по значению, поэтому изменения, которые вы делаете внутри "addNodo", являются локальными.

Вам нужно изменить функцию addNodo, чтобы она фактически получала направление, в котором находится список.

void addNode(node_t **list, int x){
  ...
  if(*pointer==NULL){
    *list = temp;
 }
}

Тогда в своей основной вы должны использовать:

addNode(&list, 1);
0 голосов
/ 20 апреля 2011

Вы совершаете классическую ошибку:

void addNodo(node_t * list, int x)
...

list = temp;
return;

list не изменяется в вызывающем абоненте (main ())

Вы можете изменить значения в памяти, на которые указывает list, но вы не можете изменить значение list, и вызывающее лицо увидит его.

Чтобы сделать это, вам нужно передать указатель на указатель в функцию:

void addNodo(node_t **list int x)

Это позволяет изменить список пунктов, выполнив:

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