简体   繁体   中英

C: Segmentation Fault — Stack implementing a Linked List

The program is relatively simple, and is only suppose to take in a text file of a semicolon-delimited value/string/line, reverse the order of the values, put it all back together, and output to a new file. There are specifications, however, that we must use a stack that implements a simple Linked List data structure. I'm pretty new to C, and am just picking up the basics of pointers (I come from Java and .NET, and this is a nightmare for me to grapple with lol). Also, the specifications specifically say that the push() function MUST take in the "old top of stack (node)" and the "value to push", and return the updated pointer to the top of the stack. Also, pop() MUST take in as parameters a "pointer of a pointer to the current top of the stack", and return the value of the popped node.

We are suppose to compile with gcc -o progname progname.c -Wall -m32 -O. The source compiles just fine, but when attempting to build the stack and such with an actual sample file, I receive a Segmentation Fault. I've run my code through gdb, however, and it's saying that Segmentation Fault is occurring at my "push((values -> head), str1);" call in main(). Since this is the call to push(), I'm guessing there's more fundamental logic error I'm overlooking in my linked list and/or stack.

I've exhausted my brain at this point, and cannot for the life of me figure out where I'm going wrong. If anyone can provide me some assistance, I'd be forever grateful.

Also, if some of the code appears ugly, I apologize. I've only been working with C for about 2 weeks now

A sample input file would be:

23414;-5224;23;569;

and expected output file would be:

569;23;-5224;23414;

Here's what I've developed so far:

#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;
}
Stack *values;

This "values" seems not initialized.

What you need is:

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

You are pushing the same address on the stack (char str1[128]) all the time. It is also a local variable.

Instead you need to read in the values and allocate heap for them, then add the heap object on the stack and free it when you push.

eg

char* str1 = malloc(128);

also more importantly you dereference values before creating a stack since values is just a pointer:

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

you need to first create the stack so that values point to something:

values = malloc( sizeof(Stack) );

sidenote: it is not good practice to use capital letters for variable names, normally macros are defined with capital letters in C.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM