2013-12-02 3 views
0

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

Мой объектный файл:

typedef struct list { 
    char *key; 
    char *value; 
    struct list *next; 
} List; 

void db_init(List *list) { 
    list = malloc(sizeof(db_sizeOfStruct())); 

    list->next = NULL; 
    list->key = NULL; 
    list->value = NULL; 
} 

void db_delete(char *key, List *list) { 
    List *prev; 
    db_init(prev); 
    int first = 1; 

    while(list != NULL) { 
     if(strcmp(key, list->key) == 0) { 
      if(first == 1) { 
       list = list->next; // This is supposed to delete the first item in the list but it does not work... 
      } else { 
       prev->next = list->next; 
      } 
      return; 
     } else { 
      prev = list; 
      list = list->next; 
      first = 0; 
     } 
    } 
} 

И в главном файле для программы:

void delete(List *list) { 
    printf("key: "); 
    char *key; 
    key = malloc(sizeof(key)+1); 
    readline(key, 128, stdin); 

    if(key != NULL) { 
     db_delete(key, list); 
    } 
} 

int main(void) { 
    delete(list); 
    return 0; 
} 
+0

Ваша функция db_init() является грубой. он должен вернуть список malloced (либо по возврату, либо по эталонному параметру) –

+1

Кроме того, в 'delete' вы выделяете 5 байтов для' key' (4 байта для 'sizeof (key)' as 'key' является указателем ('char *') плюс 1. Думаю, вам нужно больше времени работать на C/C++, а затем начать работу над более сложными темами, например, связанными списками. – Isaac

ответ

0

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

Наилучшим решением является сделать его вернуть новую главу списка:

List * db_delete(List *list, const char *key); 
0

вы должны изменить список переменной в главном. Это может быть достигнуто, если передать указатель на указатель на вашу функцию удаления, как «удалить (список ** списка)»

+0

Я пробовал это, но тогда мне также нужно будет изменить вызов db_delete в db_delete (key, * database)? И тогда в db_delete каждое вхождение базы данных будет * базой данных, а затем оператор «->» не работает ... – theva

+0

«база данных« может стать »(база данных *) «отметьте скобки –

+0

, так что это:« list = list-> next; », было бы следующим: '* list = (list \ *) -> next' ;? Я старался, чтобы я просто написал его как '* list = * list-> next; ' – theva

1

Там несколько вопросов здесь

Прежде всего вы называете db_init, который выделяет элемент даже если вы хотите его удалить.

Во-вторых, вам нужно учитывать, что если первый элемент удален, вам нужно вернуть адрес нового первого элемента, но с вашей текущей функцией вы этого не сделаете.

Прототип должен выглядеть следующим образом вместо

void db_delete(char *key, List **list) 

или, может быть немного аккуратным, возвращая первый элемент:

List* db_delete(char *key) 

Так что функция может выглядеть примерно так

List* db_delete(const char *key, List *list) 
{ 
    // normally it is not a good idea to use an argument 
    // to a function as a loop variable in a function 
    // also check arguments to avoid segfaults and 
    // other headaches 
    if (key != NULL && list != NULL) 
    { 
    List* cur = list; 
    List* prev = NULL; 

    for (; cur != NULL; cur=cur->next) 
    { 
     // identify if it is the one to delete 
     if (!strcmp(key, cur->key)) 
     { 
     if (prev != NULL) // if not first 
     { 
      List* tmp = cur; 
      prev->next = cur->next; 
      free(tmp); 
      return list; 
     } 
     else // if first 
     { 
      List* tmp = cur; 
      List* next = cur->next; 
      free(tmp); 
      return next; 
     } 
     } 
    } 
    prev = cur; 
    } 
    return list; 
} 

Еще один совет - использовать calloc вместо malloc, тогда вы не необходимо инициализировать следующий, prev, так как они уже будут 0.

+0

Выглядит хорошо но код предполагает, что в структуре есть поле prev, я не могу изменить структуру, чтобы ее содержать. – theva

+0

обновлен код –

Смежные вопросы