1

I am doing very basic dynamic allocation practice in C and I came across this issue: when I am trying to call free() with the pointer returned by malloc(), I am getting Invalid pointer error during run time.

When I remove free() from code, it works fine. The pointer that I am using is not modified anyhow after returned by malloc (except the casting). So that rules out some suggestion I found online. Below is my code:

#include <stdio.h> #include <stdlib.h> int main() { int num = 0; //printf("Enter a number: "); //scanf("%d", &num); char* p = (char*)malloc(16*sizeof(char)); printf("%p", p); if(p) { p = "mark"; printf("\n%s\n", p); free(p); //when removed no error } return 0; } 

Following is the error message:

0xa26010 mark *** Error in `./a.out': free(): invalid pointer: 0x00000000004006b7 *** ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fa968aed7e5] /lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7fa968af637a] /lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fa968afa53c] ./a.out[0x40061a] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fa968a96830] ./a.out[0x4004e9] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 08:03 6815746 /home/kushal/Documents/GATE/prac_C/a.out 00600000-00601000 r--p 00000000 08:03 6815746 /home/kushal/Documents/GATE/prac_C/a.out 00601000-00602000 rw-p 00001000 08:03 6815746 /home/kushal/Documents/GATE/prac_C/a.out 00a26000-00a47000 rw-p 00000000 00:00 0 [heap] 7fa964000000-7fa964021000 rw-p 00000000 00:00 0 7fa964021000-7fa968000000 ---p 00000000 00:00 0 7fa968860000-7fa968876000 r-xp 00000000 08:03 39719295 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fa968876000-7fa968a75000 ---p 00016000 08:03 39719295 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fa968a75000-7fa968a76000 rw-p 00015000 08:03 39719295 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fa968a76000-7fa968c36000 r-xp 00000000 08:03 39714902 /lib/x86_64-linux-gnu/libc-2.23.so 7fa968c36000-7fa968e36000 ---p 001c0000 08:03 39714902 /lib/x86_64-linux-gnu/libc-2.23.so 7fa968e36000-7fa968e3a000 r--p 001c0000 08:03 39714902 /lib/x86_64-linux-gnu/libc-2.23.so 7fa968e3a000-7fa968e3c000 rw-p 001c4000 08:03 39714902 /lib/x86_64-linux-gnu/libc-2.23.so 7fa968e3c000-7fa968e40000 rw-p 00000000 00:00 0 7fa968e40000-7fa968e66000 r-xp 00000000 08:03 39714844 /lib/x86_64-linux-gnu/ld-2.23.so 7fa969046000-7fa969049000 rw-p 00000000 00:00 0 7fa969064000-7fa969065000 rw-p 00000000 00:00 0 7fa969065000-7fa969066000 r--p 00025000 08:03 39714844 /lib/x86_64-linux-gnu/ld-2.23.so 7fa969066000-7fa969067000 rw-p 00026000 08:03 39714844 /lib/x86_64-linux-gnu/ld-2.23.so 7fa969067000-7fa969068000 rw-p 00000000 00:00 0 7ffcf8e4b000-7ffcf8e6c000 rw-p 00000000 00:00 0 [stack] 7ffcf8f1d000-7ffcf8f20000 r--p 00000000 00:00 0 [vvar] 7ffcf8f20000-7ffcf8f22000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted (core dumped) 
9
  • 6
    You can only free the pointer value that was returned by malloc, but you are overwriting it with another value (p = "mark") that can't be freed because it was not obtained from malloc or one of its cousins. Commented Feb 14, 2019 at 17:21
  • 3
    Explicit casting of a malloc is not necessary: stackoverflow.com/questions/605845/… Commented Feb 14, 2019 at 17:23
  • 1
    You can't free the stack. When you write p = "mark" you said p = stack_pointer_of("mark"). The right way it's strcpy(p, "mark") // value_of_p = "mark". Commented Feb 14, 2019 at 17:25
  • 1
    @Initerworker : While assigning p to the address of the literal string constant "mark" is the issue, the string is not stored on the stack. It will be a static const. Commented Feb 14, 2019 at 18:33
  • 1
    OT: for robustness, immediately after the call to malloc() should be: if( !p ) { perror( "malloc failed" ); exit( EXIT_FAILURE ); } then the if() statement can be removed since the code would have already checked the returned value from malloc() Commented Feb 15, 2019 at 2:30

4 Answers 4

8

You have a variable p that points to the memory returned by malloc. Then you change the variable p to point to the memory occupied by the string literal "mark". When you try to delete it, you are trying to delete the string literal.

In short, the line p = "mark" is not doing what you think it's doing. It isn't copying that value into the memory returned from malloc.

Try changing that line to strcpy(p, "mark") and I suspect things will start working better.

(That being said, I shouldn't even mention strcpy because it's so unsafe and there are alternatives that will prevent buffer overrun problems. But that's a separate question, and there are a lot of discussions about it here on SO.)

Sign up to request clarification or add additional context in comments.

Comments

0

The problem is that p does not point to memory allocated using malloc(). Instead, it contains a pointer into constant "mark", so basically you are trying to delete a literal which is not allowed

int main() { int num = 0; //printf("Enter a number: "); //scanf("%d", &num); char* p = (char*)malloc(16*sizeof(char)); printf("%p", p); if(p) { strcpy(p,"mark"); printf("\n%s\n", p); free(p); //when removed no error } return 0; } 

usage of strcpy will solve the problem

Comments

0

There is an error in your code:

 p = "mark"; 

is wrong, p is a pointer i.e. it is suppose to contain an address value. you cannot assign to it a string. You must use the functions provided by the standard library such as strcpy or strncpy (header: string.h).

#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int num = 0; //printf("Enter a number: "); //scanf("%d", &num); char* p = (char*)malloc(16*sizeof(char)); printf("%p", p); if(p) { //*p = st"mark\0"; strcpy(p, "mark"); printf("\n%s\n", p); free(p); //when removed no error } return 0; } 

Comments

-1

You don't need to allocate memory to a char I think, just declare it and when the compiler converts it to assembly it'll do its magic

I think you have some debug mode on

if you want to try malloc() try with ints first

int *ptr; ptr = malloc(sizeof(int)); ptr = 20; printf("%d", ptr); ptr = NULL; free(ptr); return 0; 

with character arrays you just do char *description; and you can do description = "hello world" (without asterisk).

if you want to print a pointer to character array, just do printf("%s", description);

2 Comments

Are you intentionally making the exact same error OP is, by overwriting the value returned by malloc? As well as calling free AFTER NULLing the pointer?
It's a benign error because free(NULL) does nothing, but there is a memory leak.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.