Segmentation fault na Function read_line

Asked

Viewed 52 times

0

I have a Function that returns a string from a row of a file, but when I run it I get a message from Segmentation fault. Here’s the code:

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "parser.h"

const int MAX_CHAR_PER_LINE = 100;

int main()
{
    FILE *h = fopen("/home/test.txt", "r");
    char *line = read_line(h);

    printf("%s", line);

    return 0;
}

int parse(FILE *header)
{

   return 0;
}

char* read(FILE *header, int bytes)
{
    char *ret_v = (char*) malloc(bytes);
    fread((void*) ret_v, 1, bytes, header);

    return ret_v;
}

char* read_line(FILE *header)
{
    char *line = (char*) malloc(MAX_CHAR_PER_LINE);
    char ch = getc(header);
    int count = 0;

    while (ch != 255 && ch != '\n')
    {
        line[count] = ch;
        ch = getc(header);
        count++;
    }
    line[++count] = '\0';

    char *ret_line;
    memcpy(ret_line, line, strlen(line));
    free(line);

    return ret_line;
}

I don’t understand why this mistake is happening, apparently I did everything right. : / Note: I just discovered that the "error" is not in the code, but in the compiler. I compiled with TCC and the segfault error appeared, but when I compiled with gcc Function returned the correct value.

  • But if the goal is to read the entire file and put into one char *, because you didn’t just define this in fread and used fseek to know the size of the rewind to return the pointer to the beginning before using the fread? ... Of course, if the file is large, I think it’s not worth it, it would be better to read with limits and print on the screen (which seems to be the goal)

  • Yes the file will be great, that’s why I want to read line by line.

  • So if you want to read line by line is doing this "wrong" (from my point of view), allocating a large file in memory seems like a bad strategy, I have to understand your goal to at least try to indicate a strategic solution of how to do this. Simply reading by reading does not seem the real purpose of your application, if you can give an idea of what you want to do with the data read I can try to point a way.

  • I just "solve the problem", my goal is to extract functions within the headers to soon create an IDE for C.

  • @Carloshenrique answer and ask and accept, it is better to leave the record.

  • So @Carloshenrique can do this without throwing everything into memory, you can type create a Token identifier (assuming you are creating a "language of your own"), the Tokens would be reserved words of their functions that we could detect at each loop and only allocate in memory what is important ... seriously you do not need to allocate the entire file in memory, this will kill your application, or at least give CRASH.

  • I understand, but in case I would allocate in memory only one line, and from that line would identify the tokens

  • So, but the error is probably occurring in your script because it did this, allocated everything at once, what you need to do is what I commented earlier, read piece by piece and only allocate what interests you.

  • Could you send me an example?

  • How is the content format of this your . txt?

  • Text format, ASCII text

  • Like char only stores a single byte (and that byte has signal bit), I believe the comparison ch != 255 will not return what you want. By the way, for reasons of optimization, one reads a row of bytes at once, instead of always going in the file to pull a new character. Not that that’s wrong, it’s just unnecessarily slow.

Show 7 more comments

1 answer

0


There should be no problem with your compiler. Your code problem is at the end of the function read_line:

char *ret_line;
memcpy(ret_line, line, strlen(line));
free(line);
return ret_line;

The signature of the memcpy function is as follows:

void * memcpy ( void * destination, const void * source, size_t num );

What the function memcpy does is copy num bytes at the address pointed by source and puts these bytes at the address pointed by destination. Which means that memcpy does not allocate memory to pointer destination. You are copying bytes to an uninitialized pointer. This is the cause of Segmentation fault. Then it would be right to do so:

char *ret_line = (char*) malloc(strlen(line)); 
memcpy(ret_line, line, strlen(line));
free(line);
return ret_line;

But to copy strings there is a better alternative, which would be the strcpy. The code would be pretty much the same, you just wouldn’t have to specify the number of bytes, because the function copes until you find the ending character.

But in fact you don’t even need any of this, you could return the pointer line. And don’t forget to release the memory in the main function.

  • Came late, I had already solved the problem

Browser other questions tagged

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