Как правильно добавить символ * в связанный список без ошибки сегмента - PullRequest
1 голос
/ 05 февраля 2020

Я пытаюсь добавить значения (символьные массивы путей к файлам) в связанный список. Я продолжаю получать ошибку Seg от своей функции _add, и я не уверен, как это исправить. Я пробовал много разных способов написания функции, но я не получил нигде. Ответ кажется простым, я просто не могу его получить. Вот мой код для функции _add:

    typedef struct cplist {
        char *path; 
        int cpid;
        time_t  tv_sec;   
        suseconds_t tv_usec;
        struct cplist *next;
    } cplist;

cplist *cpl_add(cplist *head, char *path){
    cplist *current = head;
    while(current->next != NULL){
        current = current->next;
    }

    current->next = (cplist*) malloc(sizeof(cplist));
    current->next->path = path;
    current->next->next = NULL;
}

А вот мой код из основной программы. Я читаю необязательный флаг '-v', затем целое число, а затем пути, которые необходимо добавить в связанный список:

int main(int argc, char* argv[]){
    int i, j;
    char *p;
    char *key;
    cplist *head = NULL;
    for(i = 0; i < argc; i++){
        if(strcmp(argv[1], "-v") == 0){
            key = argv[2];
            for(j = 3; j < argc; j++){
                p = argv[j];
                cpl_add(head, p);
            }
        } else {
            key = argv[1];
            for(j = 2; j < argc; j++){
                p = argv[j];
                cpl_add(head, p);
            }
        }
    }

Ответы [ 2 ]

0 голосов
/ 05 февраля 2020

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

И вы должны сделать копию переданной строки.

Более того, функция имеет тип возвращаемого значения, который отличается от void, но ничего не возвращает.

Кроме этого, в этом операторе есть ошибка

current->next = (cplist*) malloc(sizeof(head));

Вы не выделяете память для узел. Вы выделяете память для указателя. Это не то же самое.

Функция может выглядеть следующим образом.

#include <stdlib.h>
#include <string.h>

//...

int cpl_add( cplist **head, const char *path )
{
    cplist *current = malloc( sizeof( cplist ) );

    int success =  current != NULL;

    success = success && ( current->path = malloc( strlen( path ) + 1 ) );

    if ( !success )
    {
        free( current );
    }
    else
    {
        strcpy( current->path, path );
        current->next = NULL;

        while ( *head != NULL ) head = &( *head )->next;

        *head = current;
    }

    return success;
}

И вызывать функцию, например, как

cpl_add( &head, argv[j] );
0 голосов
/ 05 февраля 2020

Когда вы звоните cpl_add(head, p), вы на самом деле звоните cpl_head(NULL, p).

Затем вы звоните NULL->next, что взрывается.

  • Инициализируйте head с помощью malloc перед добавлением в дерево.
  • Будьте обязательно установите указатели связанного списка в этом элементе на NULL.

Другие вещи, которые вы можете сделать:

  • Избавьтесь от бесполезной переменной p, просто вызовите ее с помощью cpl_add(head, argv[j]) напрямую, чтобы избежать двусмысленности.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...