Связанный список не работает - PullRequest
0 голосов
/ 10 марта 2011

У меня есть следующий код, когда я добавляю узлы, почему он сбрасывает все узлы к самым последним данным узлов?Если предположить, что все остальное в кодах работает правильно, анализ и т. Д. Может выявить проблему со списком.См. Вывод внизу.

typedef char* string;
typedef struct linked_list listType;
typedef struct linked_list* linked_list;
typedef struct node NodeType;
typedef struct node* Node;

typedef enum boolean{
    true = 1,
    false = 0
}boolean; 

struct node{
    Node next;//next node in the list
    string *transData;//listAdd--->string data[]
};

struct linked_list{
    Node head;//first node in the list
    int size;//size of list, number of nodes in list
};

boolean add(linked_list list, string *data)
{
    boolean retval = false;//default retval is false
    Node nod;//node to add
    nod = (Node)malloc(sizeof(NodeType));
    nod->transData = data;
    nod->next = NULL;

    //list size is 0
    if(list->head == NULL)
    {
        list->head = nod;
        printf("First Node added: '%s'\n", nod->transData[0]);fflush(stdout); 
        retval = true;
    }

    //nodes already in list
    else
    {
        printf("List with nodes already\n");
        fflush(stdout); 
        Node node = list->head;

        //iterating through nodes
        while(node->next != NULL)
        {
            node = node->next;
        }//while

        node->next = nod;
        printf("Node added: '%s'\n", nod->transData[0]); fflush(stdout);
        retval = true;
    }

    list->size+=1;
    return retval;//success
}

/**
 * Returns the size of the list.
 */
int listSize(linked_list list)
{
    return list->size;
}

/**
 *Can only print with 2 or more elements
 */
void printList(linked_list list)
{
    int i=0;
    Node nod = list->head;
    int length = listSize(list);
    printf("ListSize:%d\n",listSize(list));
    fflush(stdout);

    while(nod->next != NULL)
    {
        printf("Node %d's data: %s\n", i, nod->transData[0]);
        fflush(stdout);
        nod = nod->next;
        i++;
    }
}//printlist

Вывод:

trans 5 5  
Argument 1: trans  
Argument 2: 5  
Argument 3: 5  
Last spot(4) is: (null)  
name of command: trans  
ID 1  
First Node added: 'trans'  
ListSize:1
>>check 4  
Argument 1: check  
Argument 2: 4  
Last spot(3) is: (null)  
name of command: check  
ID 2  
List with nodes already  
Node added: 'check'  
ListSize:2  
Node 0's data: check  
>>trans 4 4  
Argument 1: trans  
Argument 2: 4  
Argument 3: 4  
Last spot(4) is: (null)  
name of command: trans  
ID 3  
List with nodes already  
Node added: 'trans'  
ListSize:3  
Node 0's data: trans  
Node 1's data: trans  
>>check 5  
Argument 1: check  
Argument 2: 5  
Last spot(3) is: (null)  
name of command: check  
ID 4  
List with nodes already  
Node added: 'check'  
ListSize:4  
Node 0's data: check  
Node 1's data: check  
Node 2's data: check  

Ответы [ 3 ]

3 голосов
/ 10 марта 2011

(ОП говорит мне, что узлы должны иметь массивы строк, поэтому указатель на указатель действительно корректен).

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

Сначала я бы избавился от этих typedef.Я не знаю, сколько ясности они действительно добавляют.

Далее необходимо выделить новое хранилище для каждой строки.Функция стандартной библиотеки strdup () - это удобный способ сделать это:

//  Turns out it's a fixed-size array, so we can blow off some memory 
//  management complexity. 
#define CMDARRAYSIZE 21

struct node {
    Node next;
    char * transData[ CMDARRAYSIZE ];
};

//  Node initialization:

int i = 0;

struct node * nod = (struct node *)malloc( sizeof( struct node ) );
//  Initialize alloc'd memory to all zeroes. This sets the next pointer 
//  to NULL, and all the char *'s as well. 
memset( nod, 0, sizeof( struct node ) );

for ( i = 0; i < CMDARRAYSIZE; ++i ) {
    if ( NULL != data[ i ] ) {
        nod->transData[ i ] = strdup( data[ i ] );
    }
}

... но затем убедитесь, что когда вы освобождаете каждый узел, вы вызываете free (nod-> transData [n])для каждого ненулевого строкового указателя в nod-> transData.С не является трудосберегающим языком.

1 голос
/ 10 марта 2011

Не главная проблема, но ваш printList не распечатает последний элемент.

Вместо while(nod->next != NULL) используйте while(nod != NULL)

1 голос
/ 10 марта 2011

Возможно, ваша проблема связана с копированием указателя.Вы, вероятно, ссылаетесь на один и тот же буфер во всех ваших узлах.Попробуйте скопировать строковые данные, например, с помощью strdup.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...