2017-01-31 10 views
1

Итак, я пытаюсь создать Stack of Strings в C, и, похоже, у меня проблема. Цель состоит в том, чтобы прочитать файл и распечатать его в обратном порядке. Я решил, что стек будет наиболее подходящим способом сделать это (я понимаю, что есть более простые способы сделать это, но я хотел бросить вызов себе с использованием структур).C Проблемы со стеком строк

Вот мой толчок/printStack код:

void push(struct LineStack * stack, char * line) 
{ 
    if(!stack->head) 
    { 
     stack->head = malloc(sizeof(struct entry *)); 
     stack->head->data = line; 
     stack->head->next = NULL; 
     stack->top = stack->head->data; 
     stack->size++; 
    } 
    else 
    { 
     struct entry * entry = malloc(sizeof(struct entry *)); 
     entry->data = line; 
     entry->next = stack->head; 
     stack->head = entry; 
     stack->top = stack->head->data; 
     stack->size++; 
    } 
}                             

void printStack(struct LineStack * stack) 
{ 
    while(stack->head) 
    { 
     printf("%s\n", stack->head->data); 
     stack->head = stack->head->next; 
    } 
} 

А вот главная/tempFile.txt:

int main(void) 
{ 
    struct LineStack * stack = newStack(); 
    char * fileName = "tempFile.txt" 
    char line[SIZE]; 

    FILE * fp = fopen(fileName, "r"); 

    while(fgets(line, 128, fp) != NULL) 
     push(stack, line); 

    printStack(stack); 

    free(stack); 

    return 0; 
} 

tempFile.txt:

Lets begin 
We'll say 2 + 2 = 4 
But then go ahead and prove that 1 + 2 + 3 + 4 + ... = -1/12 
How can this be? 
How can this be? 

Когда я пытаюсь запустите код, он напечатает правильное количество строк в файле (5), но только распечатает «Как это может быть». Теперь я попытался использовать GDB, чтобы понять, в чем проблема, и кажется, что push-вызовы работают правильно. Каждый вызов помещает другую строку в другую ячейку памяти, поэтому я должен предположить, что связанный список, который составляет стек, отлично работает. Я пропустил что-то глупое и маленькое?

Для справки, здесь является запись/LineStack декларации:

struct entry 
{ 
    char * data; 
    struct entry * next; 
}; 

struct LineStack 
{ 
    struct entry * head; 
    char * top; 
    int size; 
}; 

Спасибо заранее.

+0

где находится 'newStack()'? –

+0

newStack() и SIZE не определены – BlueCollar

+1

Вы должны избегать большинства, если не всех дубликатов специального кода в функции 'push()'. –

ответ

0

Ваш main() считывает каждую строку в локальный массив line. Затем он передает (указатель на) этот массив для функции push(). Эта функция просто хранит этот указатель в стеке - данные не копируются, а только указатель. В результате все ваши записи стека содержат указатели на один и тот же массив; когда вы печатаете их, этот массив содержит последнюю строку, считанную из файла, и это то, что вы печатаете, столько раз, сколько вы читаете.

Необходимо скопировать входные строки. Если у вас есть strdup() (функция POSIX, но не стандартная C), то это самый простой способ сделать такую ​​копию. В противном случае [strlen() +] malloc() + strcpy() будет обычным способом делать копии ваших строк. В любом случае, помните, что вы несете ответственность за освобождение каждой части динамически распределенной памяти, когда вы закончите с ней, прежде чем позволить последнему указателю на ее утери.

+0

Благодарим вас. Это сработало отлично. –

0

Помимо того, что уже сказал @JohnBollinger, у вас есть следующие проблемы:

stack->head = malloc(sizeof(struct entry *)); 

Здесь вы выделить кусок памяти размером с указателя к struct entry, а не размер самого struct entry. Оно должно быть:

stack->head = malloc(sizeof(struct entry)); 

Та же проблема возникает, когда вы выделяете память для stack->entry.