Бесконечный цикл при использовании 'for' с указателем в качестве переменной цикла

Я совершенно новичок в кодировании и застрял с проблемой. Я пытался решить это сам и много гуглил, но у меня до сих пор нет решения этой проблемы. Может быть, один из вас может помочь?

Это мой код:

int main(int argc, char **argv) {
    struct node {
        char *str;
        int count;
        struct node *next;
    };

    struct node head = { argv[1], 1, NULL };
    for (int i = 2; i < (argc); i++) {
        for (struct node *p = &head; (p != NULL); p = p->next) {
            printf("%s,%s\n", argv[i], p->str);
            if (strcmp(argv[i], p->str) == 0) {
                printf("case1\n");
                p->count++;
                break;
            }
            else if ((strcmp(argv[i], p->str) != 0) && p->next) {
                printf("case2\n");
                printf("Adresse, auf die p zeigt: %p", &p);
                continue;
            }
            else if ((strcmp(argv[i], p->str) != 0) && (!p->next)) {
                printf("case3\n");
                struct node *oldhead = &head;
                head.str = argv[i];
                head.count = 1;
                head.next = oldhead;
                break;
            }

        }
    }

    // Print how many times each string appears

    return 0;
}

Цель состоит в том, чтобы создать связанный список, который содержит все аргументы, которые я дал main() при вызове программы. Если есть дубликаты, структура должна их посчитать. Например, если я назову программу как ./a.out foo fool foo результат должен быть списком длины два, где первый элемент содержит строку "foo" и считать 2, а второй элемент содержит строку "fool" и имеет счет 1, Проблема заключается в else ifЗаявление во внутренней для цикла. Это единственная часть, где должен фактически использоваться внутренний цикл for и назначать p->next в p, К сожалению, этого не происходит. В результате внутренний цикл for запускается снова и снова, и указатель p постоянно указывает на один и тот же адрес (я использовал printf, чтобы выяснить это).

Кто-нибудь из вас имеет представление, в чем может быть проблема здесь? Я перепробовал все, что мог, и попытался найти решение онлайн...

Большое спасибо!!!

3 ответа

Решение

Проблема в этой части кода

   else if ((strcmp(argv[i], p->str) != 0) && (!p->next)) {
        printf("case3\n");
        struct node *oldhead = &head;
        head.str = argv[i];
        head.count = 1;
        head.next = oldhead;
        break;
    }

Вам нужно выделить новую структуру и затем поместить ее адрес в последнюю запись структуры.

       else if ((strcmp(argv[i], p->str) != 0) && (!p->next)) {
            printf("case3\n");
            struct node *oldhead = p;
            p = (struct node *) malloc(sizeof(node));
            if (p == NULL) { .... manage the error ... }
            oldhead->next = p;
            p->str = argv[i];
            p->count = 1;
            p->next = NULL;
            break;
        }

Теперь вы создаете узлы и связываете их вместе. Вы эффективно обновляли то же самое node до.

        struct node *oldhead = &head;
        head.str = argv[i];
        head.count = 1;
        head.next = oldhead;

Это не создает новый узел. Это просто создание новой ссылки на тот же узел, что вызывает бесконечный цикл при попытке прочитать связанный список до конца. Поэтому ваша программа имеет только один узел. Вы должны на самом деле выделить и создавать новые.

Основная проблема здесь

struct node *oldhead = &head;

что вы должны сделать malloc:

struct node *oldhead = (struct node*) malloc(sizeof(struct node));

так что вы действительно выделяете часть памяти для своего нового узла. И потому что у вас есть malloc, ты должен сделать free в конце вашей программы:

while(...) {
   free(deepest_node)
}

способ, которым вы выполняете цикл выше, состоит в том, чтобы пройти от самого дальнего узла в связанном списке до самого конца head,

Другая проблема заключается в том, что вы не должны добавлять свой новый узел к head:

head.next = oldhead;

но должно быть p, который является последним узлом в вашем связанном списке:

p -> next = oldhead;
Другие вопросы по тегам