Simple test of malloc and free with int pointer causes double free or corruption error

To learn more about pointers I wrote just a simple test function which creates a pointer, allocates space ande after some output on the shell the space shall be freed.

void main() {
  int *p = (int*) malloc(sizeof(int));
  int a = 42;
  printf("p: %x\n", p);
  printf("*p: %d\n", *p);
  printf("a: %s\n", a);
  printf("&a: %x\n", &a);
  p = &a;
  printf("p: %x\n", p);
  printf("*p: %x\n", *p);

  //Until now everything works as expected
  free(p); //ERROR
  // printf("p: %x\n", p); // Shall cause error, because space was freed
  // printf("*p: %x\n", *p); // Shall cause error, because space was freed
}

At first runs everything was ok. free(p) caused no error. Then I tried the same test with a struct and got the double free error. "Ok, maybe I do something wrong, lets go to the start", I thought and Ctrl+Z everything to this one above, like it was before. Now I still get this error. Why? Thats a newbie question, I know. The code above you can find everywhere in the web as a simple demonstration of malloc and free. Like here: Hope, someone can tell me what I do wrong.


ANSWERS:


The pointer passed to free() must be returned from a previous call to malloc() (or calloc() or realloc()). This is not the case as p has the address of a after:

p = &a;

and p is then passed to free() causing undefined behaviour.

Note that in the example on page linked in the question nowhere is the pointer being reassigned after the call to any of the dynamic allocation functions.


The comment "Shall cause error, because space was freed" in the following code snippet is incorrect:

free(p); //ERROR
// printf("p: %x\n", p); // Shall cause error, because space was freed

as it is safe to print the address of a pointer, regardless of whether the memory it has been associated with has been free() or not. It is an error if you attempt to access memory that has been free()d, so this comment is correct:

// printf("*p: %x\n", *p); // Shall cause error, because space was freed

because p is being deferenced and an attempt to read free()d memory is occurring.


This is an error:

printf("a: %s\n", a); /* Must be '%d' as 'a' is an 'int'. */

Note that:

printf("p: %x\n", p);

is also undefined behaviour: use %p format specifier for pointers. See Correct format specifier to print pointer (address)?


Do I cast the result of malloc?


void main() {
  int *p = (int*) malloc(sizeof(int));   // here is error number one.
                                         // you casted your fresh malloc'd int
                                         // to an int*
                                         // which is not what you want to do
                                         // get rid of the cast you don't need it.

   // here is where your problem continues.
  int a = 42;   // this variable A was created on the stack not the heap!!
                //you cant free this, which is what you are doing below.
  printf("p: %x\n", p);
  printf("*p: %d\n", *p);
  printf("a: %s\n", a);
  printf("&a: %x\n", &a);

  p = &a; // this is a correct statement. 
          // you getting the address of var a
          // and making pointer p point to A's contents.
  printf("p: %x\n", p);
  printf("*p: %x\n", *p);

  //Until now everything works as expected
  free(p); //ERROR: here you are trying to free var A 
           // but you cant because it wasnt dynamically allocated.
  // printf("p: %x\n", p); // Shall cause error, because space was freed
  // printf("*p: %x\n", *p); // Shall cause error, because space was freed
}

hope this helps a bit. I highly recommend that you read CH 5 on pointer in K&R(Kernegie and Richie) C programming language book. its really short and you can probly find it free online somewhere. in fact i recommond that you read the whole book. best c book out there. remember you can only free what you malloced (remember each malloc gives you blocks in memory from the heap)



 MORE:


 ? Kernighan & Ritchie malloc free logic
 ? C malloc and free
 ? How do malloc() and free() work?
 ? How do malloc() and free() work?
 ? How do malloc() and free() work?
 ? How is malloc() implemented internally?
 ? How does C free() work?
 ? How are malloc and free implemented in C?
 ? how does dynamic memory allocation work
 ? free function not working in c / objective-c