Why does this C-linked list program give a “segmentation error”?

The first function reads a file that has a bunch of 'char and puts them in a linked list. He does not work: (.

#include <stdio.h>
#include <stdlib.h>

struct list {
    char val;
    struct list* next;
};

typedef struct list element;

int lcreate(char* fname, element* list);
int ldelete(element* list);
int linsert(char a, char b, element* list);
int lremove(char a, element* list);
int lsave(char* fname, element* list);



int lcreate(char* fname, element* list) {
    element* elem = list;
    char c = 0;
    FILE * file = NULL;

    file = fopen(fname, "r");

    while ((c = getc(file)) != EOF)
    {
        if(list == NULL) {
            list = (element*)malloc(sizeof(element));
            if(list == NULL) {
                return 0;
            }
            list->val = c;
        }
        else {

            elem->next=(element*)malloc(sizeof(element));
            elem = elem->next;
            elem-> val = c;
        }
    }
    fclose(file);
    elem->next = NULL;
    return 1;
}



int main(void) {
    int i = 0;


    element * list = NULL;
    lcreate("list.txt", list);

    for(i = 0; i<4; ++i) {
        printf("%c", list->val);
        list = list->next;
    }

    return 0;
}

Fixed problem with "file" equal to zero.

0
source share
6 answers

One obvious problem here:

FILE * file = NULL;

fopen(fname, "r");

To execute fopen, you need to assign the result from fopento FILE *:

file = fopen(fname, "r");

Edit: since you are working in C, you cannot pass a pointer by reference. Alternatively, you can pass a pointer to a pointer:

int lcreate(char *fname, element **list) {

     // ...
     *list = malloc(sizeof(element));
     (*list)->next = null;
     (*list)->val = c;
// ...
}

, lcreate *list, list. , main - : list = lcreate("list.txt", list);

+6

file - NULL, .

+2

Yep - , FILE, list , lcreate(), .

lcreate() - , , .

4 main(), 4 . printf() , list - NULL.

, , , .

Update:

, , ( , , - ).

+1

main list lcreate. lcreate() list, list . list NULL, segfault list->val.

+1

. while lcreate() if malloc list, elem .

while ((c = getc(file)) != EOF)
{
    if(list == NULL) {
        list = (element*)malloc(sizeof(element));
        if(list == NULL) {
            return 0;
        }
        list->val = c;
    }
    else {

while list , elem - , elem- > next , , (, btw, , ): -

else {
    elem->next=(element*)malloc(sizeof(element));

, list , NULL, printf().

, - , . , seg .

0
source

It would be nice to check if malloc was successful by checking for an unnecessary pinter. In addition, you might want to highlight the start / first link outside of time to avoid a head zero check every time in the while loop. Of course, this is an optimization if your linked list becomes very large!

0
source

Source: https://habr.com/ru/post/1543336/


All Articles