Hello i have been struggling with my code for a while and finally found that the free() funtion is the cause. I think i am missing something about the details of how free() works.
My output is :
test test test test test
ID: 200
RELEASE YEAR: 2006
ID: 201
RELEASE YEAR: 2006
ID: 202
RELEASE YEAR: 2006
ID: 203
RELEASE YEAR: 2006
ID: 204
RELEASE YEAR: 2006
AB
Edit : Added the full code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1000 //Do not edit this macro.
typedef struct{
int film_id;
char title[255];
char description[1023];
unsigned int release_year;
char rental_duration;
float rental_rate;
unsigned char length;
float replacement_cost;
char rating[10];
char last_update[30];
} RECORD_t, *RECORD; //Do not edit this struct.
RECORD *find_by_year(int release_year, RECORD film_array, int start, int end,int *found);
int main(){
RECORD rec = (RECORD)malloc(sizeof(RECORD_t)*MAX); //Do not edit this line.
FILE *file = fopen("data.txt", "rb"); //Do not edit this line.
if (file == NULL) { //Do not edit this line.
printf("Cannot open the file.\n"); //Do not edit this line.
exit(0); //Do not edit this line.
} //Do not edit this line.
fread(rec, sizeof(RECORD_t)*MAX, 1, file); //Do not edit this line.
fclose(file); //Do not edit this line.
int i,test;
RECORD *rec_arr;
rec_arr=find_by_year(2006,rec,200,203,&test);
for(i=0;i<test;i++){
printf("ID: %d\n", rec_arr[i]->film_id);
printf("RELEASE YEAR: %d\n", rec_arr[i]->release_year);
printf("\n\n");
fflush(stdout);
}
printf("A");
fflush(stdout);
// file = fopen("data.txt", "wb"); //Do not edit this line.
// fwrite(rec, sizeof(RECORD_t)*MAX, 1, file); //Do not edit this line.
// fclose(file); //Do not edit this line.
free(rec); //Do not edit this line.
printf("B");
fflush(stdout);
free(rec_arr);
printf("C");
fflush(stdout);
return 1; //Do not edit this line.
}
RECORD *find_by_year(int release_year, RECORD film_array, int start, int end,int *found) {
RECORD *rec_arr=malloc(sizeof(RECORD)*1);
RECORD *narray;//for realloc check
int size=1,i,j;
start--;
if(rec_arr==NULL){//if malloc fails
printf("MALLOC FAILED find_by_year returning NULL\n");
fflush(stdout);
return NULL;
}
for(i=start;i<=end;i++){
if(film_array[i].release_year==release_year){
rec_arr[size-1]=&film_array[i];
size++;
narray=realloc(rec_arr,size);//increment the size by 1
//ERROR HANDLING
if(narray==NULL){//if realloc fails
printf("INNER REALLOC FAILED find_by_year");
fflush(stdout);
narray =malloc(sizeof(RECORD) * size);
if(narray==NULL){ //if malloc fails
printf("INNER MALLOC ALSO FAILED find_by_year returning NULL\n");
fflush(stdout);
return NULL;
}
for(j=1;j<size;j++){//copy
narray[size-1]=rec_arr[size-1];
free(rec_arr);
}
}
printf("test ");
fflush(stdout);
rec_arr=narray;
}
}
printf("\n");
fflush(stdout);
*found=size-1;
if(size==1)//if not found anything
return NULL;
return rec_arr;
}
From the results of debugging free(rec_arr) fails everytime what could be the problem here. I cropped the code and i am almost sure that the cropped parts are working from the debugging.
This line is incorrect:
narray=realloc(rec_arr,size);//increment the size by 1
The second argument to realloc
should be the number of bytes, not the number of records. You should multiply size
by sizeof(RECORD)
.
Here's some general recommendations about the rest of the code:
if(narray=NULL)
case. That code will almost never happen anyway , and probably will fail anyway even if it does enter. Recovering from out-of-memory is an advanced topic (especially taking into account that modern operating systems overcommit). rec
being NULL
on the first line of main, and also check the return value of find_by_year
-- if it returns NULL then you don't want to go on to do the i
loop. Your function does not set *found
in the case of returning NULL
, sometimes, so the caller has to do the null check before using the record count.