Программа C: создание связанного списка с использованием argv, argc, ошибки сегментации

У меня есть программа, которая принимает строки, используя подсказки командной строки argv и argc. Я продолжаю получать ошибку сегментации, когда запускаю код, и после долгих исследований я не могу определить, что может быть причиной этого. Может быть, проблема в том, как я выполняю код? Я использую gcc -o code code.c, затем ./code one two three, где one two three — строки, добавленные в связанный список. Любая помощь в определении того, где может быть моя ошибка, была бы здоровой.

Вот мой код:

#include <stdio.h>
#include <stdlib.h>

typedef struct list_node_s{
    char the_char;
    struct list_node_s *next_node;
}list_node;

void insert_node(list_node *the_head, char the_char);
void print_list(list_node *the_head);

int main(int argc, char *argv[]){
    char next_char;
    list_node *the_head = NULL;
    insert_node(the_head, next_char);
    the_head->next_node = malloc(sizeof(list_node));
    if(the_head == NULL){
            return 1;
    }

    the_head->the_char = 1;
    the_head->next_node == NULL;
    int the_count, the_count2;
    for(the_count = 0; the_count < sizeof(argv); the_count++){
            for(the_count2 = 0; argv[the_count][the_count2] != '\0'; the_count2++){
                    next_char = argv[the_count][the_count2];
                    insert_node(the_head, next_char);
            }
    }

    print_list(the_head);
    return (0);
}

void insert_node(list_node *the_head, char the_char){
    list_node * current_node = the_head;
    while (current_node->next_node != NULL) {
        current_node = current_node->next_node;
    }

    current_node->next_node = malloc(sizeof(list_node));
    current_node->next_node->the_char = the_char;
    current_node->next_node->next_node = NULL;
}

void print_list(list_node *the_head){
    if(the_head == NULL){
            printf("\n");
    }else{
            printf("%c", the_head->the_char);
            print_list(the_head->next_node);
    }

}

person lchristina26    schedule 17.04.2014    source источник
comment
Есть ли проблема с вырезанием и вставкой? что такое the_co$?   -  person Barmar    schedule 17.04.2014
comment
sizeof(argv) почти наверняка не то, что вы хотите использовать в качестве ограничения for. argv — это указатель, его размер никак не связан с количеством аргументов. Вот для чего нужен argc.   -  person Barmar    schedule 17.04.2014
comment
строка the_head-›next_node == NULL почти наверняка неверна. Вероятно, вы хотели сказать = (строка 27)   -  person Tobias Langner    schedule 17.04.2014
comment
next_char не инициализируется перед использованием (строка 20). Попробуйте удалить предупреждения компилятора. Оба комментария с моей стороны являются предупреждениями компилятора (VS2013)   -  person Tobias Langner    schedule 17.04.2014
comment
Когда вы вызываете insert_node(the_head, next_char) в начале main(), the_head имеет значение NULL, поэтому вы получаете ошибку, когда insert_node пытается его разыменовать. И next_char не инициализирован.   -  person Barmar    schedule 17.04.2014
comment
@Barmer: правильно, это также то, где я получаю segfault. Дополнительный совет: компилятор подсказывает, где segfault. Попробуйте использовать эту информацию или представить ее здесь, если вам нужна помощь.   -  person Tobias Langner    schedule 17.04.2014


Ответы (4)


Измените это:

list_node *the_head = NULL;
insert_node(the_head, next_char);
the_head->next_node = malloc(sizeof(list_node));

to:

list_node the_head = { '\0', NULL };

для инициализации the_head пустым узлом.

person Barmar    schedule 17.04.2014
comment
Вот о чем я говорил @Ichristina26 - person Hugo; 17.04.2014

Одна проблема в этой функции:

void insert_node(list_node *the_head, char the_char){
    list_node * current_node = the_head;
    while (current_node->next_node != NULL) {
        current_node = current_node->next_node;
    }

    current_node->next_node = malloc(sizeof(list_node));
    current_node->next_node->the_char = the_char;
    current_node->next_node->next_node = NULL;
}

Когда вы вызываете его в main, вы в основном передаете NULL, потому что вы устанавливаете the_head в NULL. Вы пытаетесь получить доступ к current_node->next_node в условиях цикла while, но из-за того, что вы передаете, вы в основном делаете NULL->next_node.

Вам нужно инициализировать голову на пустой list_node. По сути, поскольку вы используете char в качестве элемента узла, вы можете установить значение char равным 0x00, что сделает его нулевым байтом. Тогда таким образом вы знаете, что когда вы на этом значении, вы находитесь во главе.

Я не имею в виду саморекламу, но если вы хотите посмотреть на код для этого, взгляните на этот репозиторий github для Класс Barry_CS-331 Data Structures. Там есть C и C++ для структур данных. Я думаю, что у него может быть список, но если нет, вы можете использовать стек и очередь в качестве общего примера.

person Hugo    schedule 17.04.2014
comment
Так я инициализирую головку 0x00 в основном методе или в методе вставки? Или я инициализирую один из своих символов? Я попробовал несколько вещей из того, что вы сказали, и, похоже, ничего не сработало, поэтому я предполагаю, что делаю это неправильно... - person lchristina26; 17.04.2014

Я изменил ваш код, есть некоторые ошибки:

1) Основная ошибка в этом коде.

 for(the_count = 0; the_count < sizeof(argv); the_count++)
 {
      for(the_count2 = 0; argv[the_count][the_count2] != '\0'; the_count2++)
      {
          next_char = argv[the_count][the_count2];
          insert_node(the_head, next_char);
      }
 }

есть некоторые ошибки: вы не можете использовать the_count < sizeof(argv), потому что тип argv - это char* []; так что sizeof(argv) может быть 4 или 8, в зависимости от вашей ОС.

право это:

 for(the_count = 1; the_count < argc; the_count++){
    for(the_count2 = 0; argv[the_count][the_count2] != '\0'; the_count2++){
      next_char = argv[the_count][the_count2];
      insert_node(the_head, next_char);
    }   
  }

2、в этом коде есть ошибки:

list_node *the_head = NULL;
insert_node(the_head, next_char);
the_head->next_node = malloc(sizeof(list_node));
if(the_head == NULL){
        return 1;
}

the_head->the_char = 1;
the_head->next_node == NULL;

insert_node(the_head, next_char); не нужно, лучше сделайте the_head->the_char = '\0', потому что char 1 не является печатным символом.

person BlackMamba    schedule 17.04.2014

В одну сторону:

#include <stdio.h>
#include <stdlib.h>

typedef struct list_node_s{
    char the_char;
    struct list_node_s *next_node;
}list_node;

void insert_node(list_node *the_head, char the_char);
void print_list(list_node *the_head);

int main(int argc, char *argv[]){
    list_node *the_head = NULL;
    int the_count, the_count2;

    for(the_count = 0; the_count < argc; the_count++)
        {
        for(the_count2 = 0; the_count2 < strlen(argv[the_count]); the_count2++)
            insert_node(&the_head, argv[the_count][the_count2]);
        }

    print_list(the_head);
    return (0);
    }

void insert_node(list_node **the_head, char the_char){
    list_node *new_node;
    list_node *tail_node;

    /* Allocate and populate a new node. */
    new_node = malloc(sizeof(list_node));
    new_node->the_char = the_char;
    new_node->next_node = NULL;

   /* Is the_head already initialized? */ 
   if(*the_head)
       {
       /* Yes... find the tail_node. */
       tail_node = *the_head;
       while(tail_node->next)
           tail_node = tail_node->next;

       /* Append the new_node to the end of the list. */
       tail_node->next = new_node;
       return;
       }

    /* the_head was not initialized.  The new_node will be the head node. */
    *the_head = new_node;

    return;
    }

void print_list(list_node *the_head){
    if(the_head == NULL){
        printf("\n");
    }else{
        printf("%c", the_head->the_char);
        print_list(the_head->next_node);
    }
}
person Mahonri Moriancumer    schedule 17.04.2014