I'm trying to malloc() and then free() memory for the two char* fields in carinfo_t struct instance, but I'm getting an "invalid pointer" error on the following lines in main():
free(carToRemove->brand);
free(carToRemove->model);
and in freeCarinfo():
free(carinfo->brand);
free(carinfo->model);
Why? I'm a total newbie with C, and I've been researching for a day but I can't understand what's wrong.
Here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct carinfo_t
{
char *brand;
char *model;
int year;
float value;
struct carinfo_t * next;
} carinfo_t;
struct carinfo_t *createCarinfo(char *brand, char *model, int year, float value);
struct carinfo_t *addCarinfo(struct carinfo_t *carbase, struct carinfo_t *carinfo);
struct carinfo_t *removeCarinfo(struct carinfo_t *carbase, struct carinfo_t *carinfo);
void freeCarinfo(struct carinfo_t *carinfo);
void main()
{
struct carinfo_t *db = NULL;
int quit = 0;
char op;
char *brand = malloc(25 * sizeof(char));
char *model = malloc(25 * sizeof(char));
int year;
float value;
struct carinfo_t *car1 = createCarinfo("car1", "model1", 1, 10);
struct carinfo_t *car2 = createCarinfo("car2", "model2", 2, 80000.00);
db = addCarinfo(db,car1);
db = addCarinfo(db,car2);
while (quit == 0)
{
printf("Command (q/r): ");
scanf(" %c", &op);
switch (op)
{
case 'q':
quit = 1;
break;
case 'r':
printf(" brand: ");
scanf(" %[^\n]", brand);
printf(" model: ");
scanf(" %[^\n]", model);
printf(" year: ");
scanf("%d", &year);
carinfo_t *carToRemove = createCarinfo(brand, model, year, 0);
db = removeCarinfo(db, carToRemove);
free(carToRemove->brand);
free(carToRemove->model);
free(carToRemove);
carToRemove = NULL;
break;
default:
break;
}
}
free(brand);
free(model);
}
struct carinfo_t *createCarinfo(char *brand, char *model, int year, float value)
{
carinfo_t *newInfo = (carinfo_t *) malloc (sizeof(newInfo));
newInfo->brand = malloc (strlen(brand) + 1);
newInfo->model = malloc (strlen(model) + 1);
strcpy(newInfo->brand, brand);
strcpy(newInfo->model, model);
newInfo->year = year;
newInfo->value = value;
newInfo->next = NULL;
return newInfo;
}
struct carinfo_t *addCarinfo(struct carinfo_t *carbase, struct carinfo_t *carinfo)
{
carinfo->next = carbase;
return carinfo;
}
void freeCarinfo(struct carinfo_t *carinfo)
{
free(carinfo->brand);
free(carinfo->model);
free(carinfo);
}
struct carinfo_t *removeCarinfo(struct carinfo_t *carbase, struct carinfo_t *carinfo)
{
struct carinfo_t *prev = NULL;
struct carinfo_t *curr = carbase;
while(curr != NULL)
{
if ( (strcmp(curr->brand,carinfo->brand) == 0) && (strcmp(curr->model,carinfo->model) == 0) && (curr->year == carinfo->year))
{
if (prev == NULL)
{
carbase= curr->next;
prev = curr;
curr = curr->next;
freeCarinfo(prev);
}
else
{
prev->next = curr->next;
prev = curr;
curr = curr->next;
freeCarinfo(prev);
}
}
else
{
prev = curr;
curr = curr->next;
}
}
return carbase;
}
the reason why you get a runtime error (invalid point) is in your createCarInfo()
function. Your code is:
struct carinfo_t *createCarinfo(char *brand, char *model, int year, float value)
{
carinfo_t *newInfo = (carinfo_t *) malloc (sizeof(newInfo));
// ... rest of your code
Here, you ask malloc()
to allocate N
bytes. N
in our case is the size of your newInfo
variable. However, newInfo
is a pointer to a carinfo_t
structure. What you probably meant to do is allocate a carinfo_t
structure on the free-store and assign its address to your newInfo
pointer.
So the correct code should be:
struct carinfo_t *createCarinfo(char *brand, char *model, int year, float value)
{
carinfo_t *newInfo = malloc(sizeof *newInfo);
// ... rest of your code
I compiled your program on my PC and tried to remove a car from your database and did not get the runtime error.
Since you are new to C I highly recommend that you compile your source code with the Wall
option (enables all compiler warnings). This will help you in the long run of learning and understanding C.