C:分段错误 - 实现链接列表的堆栈

时间:2014-02-13 12:00:25

标签: c pointers linked-list segmentation-fault stack

程序相对简单,只是假设接受以分号分隔的值/字符串/行的文本文件,反转值的顺序,将它们全部重新组合在一起,然后输出到新文件。但是,有些规范必须使用实现简单链接列表数据结构的堆栈。我是C的新手,我只是拿起了指针的基础知识(我来自Java和.NET,这对我来说是一个噩梦,与lol争论)。此外,规范特别指出push()函数必须接受“旧堆栈(节点)”和“要推送的值”,并将更新的指针返回到堆栈顶部。另外,pop()必须将参数作为“指向当前堆栈顶部的指针”,并返回弹出节点的值。

我们假设使用gcc -o progname progname.c -Wall -m32 -O进行编译。源编译得很好,但是当尝试使用实际的示例文件构建堆栈时,我收到了分段错误。然而,我通过gdb运行我的代码,并且它说我的“推送((值 - >头部),str1)发生了分段错误;”在main()中调用。由于这是对push()的调用,我猜测我在链表和/或堆栈中忽略了更多基本的逻辑错误。

此时我已经筋疲力尽了,我不能为我的生活弄清楚我哪里出错了。如果有人能给我一些帮助,我将永远感激不尽。

另外,如果某些代码看起来很难看,我道歉。我现在只和C一起工作了大约两个星期

示例输入文件为:

23414;-5224;23;569;

和预期的输出文件将是:

569;23;-5224;23414;

这是我迄今为止开发的内容:

#include <stdio.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>

int STACK_ELEMENTS = 0;

typedef struct node {
    char *value;
    struct node *next;
} Node;

typedef struct my_stack {
    Node *head;
} Stack;

Stack *values;

bool stack_isEmpty() {
    if (STACK_ELEMENTS < 1)
        return true;
    else
        return false;
}

Node *push(Node *oldHead, char *val) {
    Node *newNode;
    newNode = malloc(sizeof(Node));
    newNode -> value = val;    

    if (oldHead == NULL) {
        values -> head = newNode;
        values -> head -> value = val;
    }

    else {
        values -> head -> next = newNode;
        values -> head = newNode;
    }
    free(newNode);
    STACK_ELEMENTS++;
    return (values -> head);
}

char *pop(Node **pHead) {
    char *val;
    if ((*pHead) != NULL) {
        Node *tempNode;
        tempNode = malloc(sizeof(Node));
        tempNode = *pHead;
        val = tempNode -> value;
        *pHead = tempNode -> next;
        free(tempNode);
        STACK_ELEMENTS--;
    }
    else
        return 0;
    return val;

}

int main(int argc, char *argv[]) {
    /*verify arguments*/
    if (argc != 3) {
        fprintf(stderr, "usage: strrev <file> <newfile>\n");
        exit(1);
    }

    char *fileIn = argv[1];
    char *fileOut = argv[2];

    /*open file streams*/    
    FILE *in = fopen(fileIn, "r");
    FILE *out = fopen(fileOut, "w");


    /*scan input file and delimt on semicolon*/
    /*input file is a single line of semicolon-delimited values*/
    char str1[128];
    while(!feof(in))
    {
        /*scan, delimiting on semicolon*/
        /*if the scanned element does not fit format, break*/
        if (fscanf(in, "%[^;];", str1) != 1) {
            break;
        }
        push((values -> head), str1);
    }

    while(!stack_isEmpty()) {
        fprintf(out,"%s;", pop(&(values -> head)));
    }

    fclose(in);
    fclose(out);
    return 0;
}

2 个答案:

答案 0 :(得分:0)

Stack *values;

这个“价值”似乎没有初始化。

您需要的是:

Stack *values = malloc(sizeof(Stack ));

答案 1 :(得分:0)

您一直在堆栈(char str1 [128])上推送相同的地址。它也是一个局部变量。

相反,您需要读取值并为它们分配堆,然后在堆栈中添加堆对象并在推送时释放它。

e.g。

char* str1 = malloc(128);

更重要的是,在创建堆栈之前解除引用values,因为values只是一个指针:

push( (values->head), str1 );

您需要先创建堆栈,以便values指向某个内容:

values = malloc( sizeof(Stack) );

旁注:对大写字母使用大写字母不是好习惯,通常用C中的大写字母定义宏。​​