Segmentation fault while reading file

Asked

Viewed 56 times

0

I have an inputstream header. h that defines a struct having a string, an int and a readc Function. In this header I define the Function init receiving as parameter a string having the absolute directory of a file, and the struct inputstream, in this file I read the file and pass the data to the source variable of inputstream. Here comes the code:

inputstream. h

#ifndef INPUTSTREAM_H
#define INPUTSTREAM_H

#include <stdio.h>

typedef struct
{
    char *source; // header source code
    int pos;

    char (*readc)();

}inputstream;

void init(const char*, inputstream*);

#endif

inputstream. c

#include "inputstream.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

inputstream *is;

char readc()
{
    return is->source[is->pos++];
}

void init(const char *file_header, inputstream *stream)
{
    memset(stream, 0, sizeof(inputstream));
    stream->readc = &readc;
    FILE *header = fopen(file_header, "r");

    if (header == NULL)
    {
        printf("Cannot open file\nExiting...\n");
        exit(EXIT_FAILURE);
    }

    fseek(header, 0, SEEK_END);
    long lenght = ftell(header);

    if (lenght <= 0)
    {
        printf("Empty file\nExiting...\n");
        exit(EXIT_FAILURE);
    }

    fseek(header, 0, SEEK_SET);
    stream->source = (char*) malloc(lenght + 2);
    //memset(stream->source, 0, sizeof stream->source);

    fread(stream->source, lenght + 1, 1, file_header);
    fclose(header);
}

When running Function init the error of Segmentation fault occurs. I have debugged and it seems that the problem is in Function fread. What’s wrong with the code?

  • Attention to typographical error of lenght that should be length and is very common in our language. How is calling the function in the main ?

  • init("/home/file.txt", &is);

1 answer

0


There are some errors in your code. My advice is when you’re coding, take your time and make sure what you did back there feels right, and go testing, rather than writing all the code and testing at the end. So in the first Segmentation fault who catches realizes that the error is in the little he has already written, and becomes easier to understand/debug.

Also always pay close attention to the warnings that the compiler gives because 99.99% of them are errors anyway. When I compile your code I see at least two warnings: one in the fread, and another on the call to init.

Moving on to problems:

  • In the main the call is made with init("/home/file.txt", &is) but the statement of is is :

    inputstream *is;
    

    Which means there’s a inputstream** which is not what the function void init(const char *file_header, inputstream *stream) waiting. This still has another problem which is, if you pass a pointer, it is because you have not allocated space for the content, so the first instruction within init:

    memset(stream, 0, sizeof(inputstream));
    

    General rule gives Segmentation fault straight as the pointer is has not been initialized, and does not point to undefined by you. Soon you will try to access a "random memory zone".

    Has two solutions or allocates space to the pointer with malloc and exchange the signature of the function init or goes for as simple as creating an object inputstream is; in the main. Following this last solution you just have to change the function readc for:

    char readc()
    {
        return is.source[is.pos++];
    }
    

    Still at this point, depending on global variables is always a bad idea. Avoid doing this.

  • The fread does not have the right parameters, nor in the right order. It has it in its code so:

    fread(stream->source, lenght + 1, 1, file_header);
    

    However, if you refer to documentation sees that the expected is:

    fread (ptr, size, count, stream)
    
    ptr    - Local na memória a guardar a informação
    size   - Tamanho em bytes de cada elemento
    count  - Quantidade de elementos, cada um com size bytes
    stream - Ponteiro para um objeto FILE como stream de entrada
    

    You have the size exchanged with the count and the stream is also not right as it should be the respective FILE*, the header.

    To be right it should be:

    fread(stream->source, 1, lenght + 1, header);
    
  • Attention to spelling error in lenght. Although it does not affect the code itself, this error is very common for us Portuguese and something we should be aware of. The correct is length.

  • I didn’t realize that I had passed a char* instead of a FILE*. The main function is not in the inputstream file. c, this made you think that I had declared inputstream as Pointer, but I declared it as a normal sctruct.

  • Already fread worked normal after I fix the error, so I learned the third parameter represents the data Chunk

  • @Carloshenrique It’s not what I see in the question code. I see inputstream *is;, logo is a Pointer.

  • But this inputstream belongs to the inputstream file. c, the main file is main. c

  • @Carloshenrique No main uses another ? This shows how important it is to always put the necessary information in the question. I may have ended up assuming something I wasn’t, because I can’t see how your main.

  • Yes that’s right, next time more

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.