I have a Problem when I try to load a file into memory as an array.
I am trying to load a file into an array and print it out again but I would like to allow the memory to grow as the file length can be arbitrary.
When I run my Program locally on my Mac it seems to Work fine but when I try it on my Ubuntu VM, I get the following error
realloc(): invalid next size
Aborted (core dumped)
My Code is as follows
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **loadfile(char *filename, int *len);
int main(int argc, char *argv[])
{
if (argc == 1)
{
printf("Usage add file\n");
return 1;
}
int length = 0;
char **words = loadfile(argv[1],&length);
printf("%d\n", length);
for (int i = 0; i < length; i++) {
printf("%s\n",words[i]);
}
printf("Done\n");
return 0;
}
char **loadfile(char *filename, int *len)
{
const int STEPSIZE = 10;
FILE *f = fopen(filename,"r");
if (!f) {
fprintf(stderr, "Can't open file\n");
return NULL;
}
int arrlen = STEPSIZE;
char **lines = (char **)malloc(STEPSIZE);
char buf[100];
int i = 0;
int counter = 2;
while (fgets(buf,100,f))
{
if (i == arrlen)
{
counter++;
arrlen += STEPSIZE;
char **newlines = (char **)realloc(lines,counter * STEPSIZE);
if(!newlines)
{
printf("Out of memory\n");
//return 2;
}
lines = newlines;
}
buf[strlen(buf)-1] = '\0';
int slen = strlen(buf);
char *str = (char *)malloc(slen + 1 *sizeof(char ));
strcpy(str, buf);
lines[i] = str;
i++;
}
*len =i;
return lines;
}
and for the life of me I cannot find the problem.
I can only assume the problem is somewhere in this section but I may be wrong:
if (i == arrlen)
{
counter++;
arrlen += STEPSIZE;
char **newlines = (char **)realloc(lines,counter * STEPSIZE);
if(!newlines)
{
printf("Out of memory\n");
//return 2;
}
lines = newlines;
}
Your Help is greatly appreciated
const int STEPSIZE = 10;
char **lines = (char **)malloc(STEPSIZE);
char **newlines = (char **)realloc(lines,counter * STEPSIZE);
You don't want to allocate 10 bytes, but memory for 10 char *
elements. Thus some subsequent access to lines[i] = str;
is invalid.
What you meant to do is:
char **lines = malloc(sizeof(*lines) * STEPSIZE);
char **newlines = realloc(lines, sizeof(*newlines) * counter * STEPSIZE);
Alternatively you can use sizeof(char*)
.
Also:
char *str = (char *)malloc(slen + 1 *sizeof(char ));
although it is correct and will work, because sizeof(char)
is 1, but it's more clearly the intention was:
char *str = malloc((slen + 1) * sizeof(char));
Also, it's good to think if you should cast the result of malloc.