I am working on a project and in this program I want to read given txt file line by line. Separate each line by space and get an array of words in that line. After that operation I want to free all mallocs but when I try to free it gives error.
FILE * filePointer;
char * lineFromText = NULL;
size_t lengthOfLine = 0;
ssize_t lastIndexOfText;
filePointer = fopen("/home/ogr/b21xxxxxxx/input5.txt", "r");
if (filePointer == NULL)
exit(EXIT_FAILURE);
char **array=malloc(sizeof(char*)*10);
int i;
for (i=0; i<10; i++) {
array[i] = malloc(10 * sizeof(char*));
}
while ((lastIndexOfText = getline(&lineFromText, &lengthOfLine, filePointer)) != -1)
{
lineFromText[lastIndexOfText-2]='\0';
char * pch = malloc(10 * sizeof(char));
strcpy(pch,strtok (lineFromText," "));
while (pch != NULL)
{
int loop;
array[0]=pch;
if(array[0]==NULL) {
printf("No test to search.\n");
exit(0);
}
for(loop=1;loop<10;loop++) {
array[loop]=strtok(NULL," ");
if(array[loop]==NULL)
break;
}
for(loop=0;loop<10;loop++) {
if(array[loop]==NULL)
break;
printf("Item #%d is %s\n",loop,array[loop]);
}
pch = strtok (NULL, " ");
}
}
fclose(filePointer);
int j;
for (j = 0; j < 10 ; j++) {
free(array[j]);
}
You can see text file from here : input5.txt
The reason of why you getting an error on free is that you are corrupting pointers originally returned by malloc. But the real reason is somewhere deeper.
Let's deal with that free error first. Here is how you allocating memory:
for (i=0; i<10; i++) {
array[i] = malloc(10 * sizeof(char*));
}
Here each of 10 array entries is assigned with pointer returned by malloc
call. Each of that pointers point on 40 or 80 byte memory chunk ( sizeof(char*)
gives 4 on x86 and 8 on x64) allocated.
To free up that memory the one should pass the pointers returned by malloc
to the free
function:
int j;
for (j = 0; j < 10 ; j++) {
free(array[j]);
}
But it doesn't work in your case because of the following code:
char * pch = malloc(10 * sizeof(char));
strcpy(pch,strtok (lineFromText," "));
while (pch != NULL)
{
int loop;
array[0]=pch;
...
for(loop=1;loop<10;loop++) {
array[loop]=strtok(NULL," ");
if(array[loop]==NULL)
break;
}
Here you overwriting the addresses originally returned by malloc
and stored in array
with the ones returned by strtok
. So all of the allocated memory is being leak, and you getting an error cause when it comes to free
your array[0]
contains pch
address (first word in the last line) and array[1]
containg pch
plus second word offset address which is already freed on first cycle iteration.
The real thing here is that you really don't need any extra memory allocations beside those that are done by getline
. Firstly you can declare a statically allocated array of pointers:
char *array[10];
instead of:
char **array=malloc(sizeof(char*)*10);
int i;
for (i=0; i<10; i++) {
array[i] = malloc(10 * sizeof(char*));
}
Then initialize pch
like this:
char *pch = strtok (lineFromText," ");
instead of:
char * pch = malloc(10 * sizeof(char));
strcpy(pch,strtok (lineFromText," "));
After processing is done, it only remains to free up lineFromText
buffer, because it gets allocated by getline
:
free(lineFromText)
instead of:
int j;
for (j = 0; j < 10 ; j++) {
free(array[j]);
}
Hope this help. Good luck.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.