I am writing some experimental code, to get better at C, I wrote below code
/*This is a test code. Some of the checks are not performed.*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person {
char *name;
char *occupation;
int age;
};
typedef struct person prn;
int main(void)
{
prn *ptr=NULL;
ptr = malloc(sizeof(ptr));//a node size of prn is created. No need to do malloc(sizeof(prn)) as variable also have same type.
ptr->name = malloc(sizeof(ptr->name) * ( strlen("Mrigendra") + 1));//
ptr->occupation = malloc( sizeof( ptr->occupation) * (strlen("SoftwareE")+1) );
ptr->name = "Mrigendra";//should use memcpy.
ptr->occupation = "SoftwareE";
ptr->age = 20;
printf("%s\n", ptr->name);
printf("%s\n", ptr->occupation);
printf("%d\n", ptr->age);
free(ptr->occupation);
free(ptr->name);
free(ptr);
return 0;
}
On executing above program I get this error
Mrigendra
SoftwareE
20
*** Error in `./a.out': free(): invalid pointer: 0x000000000040076e ***
Aborted (core dumped)
I am in this thinking that ptr is pointing to a location on heap. Also its members are also pointers and pointing to the heap, so I freed members and then free the ptr.
1.One thing come to my mind is that 'age' is also on heap and I haven't freed it. Is this the reason?
2.What is the correct way to debug it? (I have a fear its a dumb question or something obvious I missed)
3."core is dumped" where?
First,
ptr = malloc(sizeof(ptr))
should beptr = malloc(sizeof(prn))
in order to allocate enough memory to hold an object of typestruct person
.sizeof(ptr)
, in contrast, would always be8
(the size of a pointer value on a 64 bit system).Second,
ptr->name = malloc(sizeof(ptr->name) * ( strlen("Mrigendra") + 1));
should beptr->name = malloc(strlen("Mrigendra") + 1)
in order to allocate exactly the memory to hold the stringMrigendra
+ the string termination character.Third, instead of
ptr->name = "Mrigendra"
, which letsptr->name
point to a string literal, usestrcpy(ptr->name,"Mrigendra")
. Otherwise, you will laterfree
a pointer to a string literal, which is undefined behaviour.Note: instead of
malloc
+strcpy
, most systems offer a functionptr->name=strdup("Mrigendra")
, which does an appropriate malloc and the strcpy in one function.