Проблемы со списком и строками в C

#c #string #list #project

#c #строка #Список #проект

Вопрос:

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

Что я пытаюсь сделать, так это следующее: у меня есть список, содержащий x элементов. Я хочу добавить элемент p в список, затем взять каждый элемент x, добавить p к строке, которую они представляют, и добавить их в список. (список сам по себе отлично работает, просто эта операция вызывает проблемы).

Проблема в том, что когда я делаю это и когда я пытаюсь отобразить список, первые элементы x p отображаются хорошо, но после я вижу некоторые странные символы, которые не имеют ничего общего с входными данными.

Вот функции, которые я использую :

 void addFirst(struct list *l, char *key)
{
  struct node *x = createNode(key) ;
  if (l->size == 0)
  {
    l->first = x;
  }
  else
  {
    x->next = l->first;
    l->first = x;
  }
  l->size  ;
  return;
}

void showList(struct list* l)
{
    struct node *p=l->first;
    while (p!=NULL)
    {
        printf("%s n",p->key);
        p=p->next;
    }
    return;
}

void copyPlus(struct list* l,char *ch)
{
    struct node *p=l->first;
    addFirst(l,ch);
    while (p!=NULL)
    {
        int len1=strlen(p->key);
        char cat[len1 2];
        strcpy(cat,p->key);
        strcat(cat,ch);
        cat[len1 1] = '';
        printf("[%s] n",cat);
        addFirst(l,cat);
        printf("{%s} n",l->first->key);
        p=p->next;
    }
    return;
}

int main()
{
    struct list *A=createList();
    addFirst(A,"1");
    addFirst(A,"2");
    addFirst(A,"4");
    copyPlus(A,"3");
    printf("=%s= n",A->first->key); //this one works!
    printf("=%s= n",A->first->next->key);
    printf("=%s= n",A->first->next->next->key);
    showList(A);
    deleteList(A);
}
  

Я пропустил не относящиеся к делу материалы, это классический список.

Узел определен таким образом :

 struct node
{
  struct node *next;
  char *key;
};
  

После дальнейшего ivestigation выясняется, что процесс работает правильно (два //printf в copyPlus работают так, как должны). И последний //printf ничего не отображает, даже если я делаю A-> first-> next-> next-> далее.
Он показывает 3, если я делаю A-> first-> next-> next-> далее-> next.

Я действительно не понимаю, и это начинает действовать мне на нервы, код простой и короткий, и я все еще не вижу ошибки.

Может ли кто-нибудь мне помочь? Спасибо.

Комментарии:

1. Можете ли вы показать код для createNode()? Важно убедиться, что вы правильно сохраняете данные.

2. весь код находится здесь : pastebin.com/C4cunJXF Что странно, так это то, что другие ключи отображаются так, как должны.

3. Рабочее решение предоставлено в edit.

Ответ №1:

Хорошо, strcat итак, добавляет завершающий ноль к строке, вам нужно место для еще одного символа. strlen даст вам 1, вы будете выделять массив символов размером 2. Этого недостаточно — вам нужно как минимум 3 для первого символа, второго символа и завершающего нуля. Это все еще опасно, поскольку вы не знаете длину второй строки. Таким образом, наилучшим решением является char* cat = malloc(len1 len2 1) .

Текущая проблема заключается в том, что char cat[len1 2]; выделяется пространство в стеке (именно там находятся переменные локальной функции). По сути, вы сохраняете указатель на адрес внутри фрейма стека, который уничтожается после завершения функции. Первое значение работает, потому что это был ваш последний вызов функции, и до сих пор никто не решил перезаписать эту память (но любой может это сделать). Выделение с помощью malloc() будет выделено в куче, и значение будет доступно до тех пор, пока вы явно не вызовете free .

После внесения изменений вывод:

 [43]
{43}
[23]
{23}
[13]
{13}
=13=
=23=
=43=
13 23 43 3 4 2 1
  

Решение на C можно найти по адресу http://pastebin.com/xNzyLQ2N .

Комментарии:

1. Верно (я думал, что когда я использую strcat, это подразумевалось). Хотя это ничего не меняет: (

2. Не являются ли массивы строк Char в C?

3. Почти. Всегда есть дополнительный завершающий ноль — всегда 1 дополнительный элемент, который вы должны иметь в виду. Кстати, я предоставил редактирование выше.

4. Я сделал то, что вы сказали (и обновил исходное сообщение), но проблема остается почти той же, я могу получить доступ к A-> first-> key, но он не отображается через showlist.

5. Я полагаю, что это была последняя правка. Наслаждайтесь и принимайте, если это помогло.