0

Im writing a fairly simple program to read a file line by line and store it into an array of lines, my program compiles fine but it crashes everytime I run it. This is my code:

#include <stdio.h> 
#include <string.h>
#define LINESIZE 512

typedef struct { 
char **data; 
size_t nused; 
} lines_t;  

lines_t readlines(FILE *fp); 

int main(int argc,char* argv[]) { 
    FILE *fp; 
   (void)argc; 
   if((fp = fopen(argv[1],"r+")) == 0) { 
      perror("fopen"); 
   }
   readlines(fp); 
   return 0; 
}

lines_t readlines(FILE *fp) {
    lines_t line_data;
    char line[LINESIZE]; 
    char temp[20];  
    int num_lines = 0; 
    (*line_data.data) = (char *)malloc(LINESIZE); 
    while(fgets(line,LINESIZE,fp)) { 
        sscanf(line,"%s\n",temp); 
        strcpy(line_data.data[num_lines], temp); /* Program crashes here */
        num_lines++;  
    } 
    return line_data; 
} 

The line where I try to copy my array is giving me trouble, So my question is, How do I copy my character array temp into the char **data inside struct lines_t if I am not doing it right?

1
  • Where is char **data is being allocated memory? you need to malloc it first inside readlines Commented Jul 13, 2015 at 3:51

3 Answers 3

3

You are dereferencing an invalid pointer here:

(*line_data.data) = (char *)malloc(15); 

line_data.data is a char **. You are trying to deference it but it is not yet set to any meaningful value. You need to allocate memory for line_data.data before you allocate memory for *line_data.data.

(char *)malloc(15) is particularly suspicious also. Where does 15 come from and what are you actually allocating memory for? Casting the result of malloc is generally considered bad practice, and in your case, rightly so, because malloc is declared in stdlib.h and you aren't including that header. If you want to allocate enough space to hold 15 char *, then use malloc(15 * sizeof(char *)) or alternatively, malloc(15 * sizeof(*line_data.data)) (here it is safe to use *line_data.data even if it doesn't point to anything, because sizeof does not evaluate its operand).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! allocating for both line_data.data and *line_data.data worked, yes I forgot to add the <stdlib.h> for malloc when I edited it
0

You can try malloc line_data.data before strcpy.

lines_t readlines(FILE *fp) {
    lines_t line_data;
    line_data.data = malloc(LINESIZE);
    *line_data.data = malloc(LINESIZE);

    return line_data; 
}

1 Comment

LINESIZE is surely not the right size to use in the first malloc
0

You first need to allocate memory.
You need to allocate both for the array of strings and string array. Here you need to have an upper limit while calling a malloc.

line_data = malloc(10* sizeof(char*));  // for example here the upper limit is 10
while(fgets(line,LINESIZE,fp)) { 
        sscanf(line,"%s\n",temp); 
        line_data.data[num_lines] = malloc(sizeof(char) * (strlen(temp)+1));
        strcpy(line_data.data[num_lines], temp); /* Program crashes here */
        num_lines++;  
    } 

1 Comment

You forgot about strings having null terminators

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.