Dynamically expanding array using realloc

I wrote the following code to find out using malloc and realloc. I initialized the pointer using malloc and then using realloc, I increase the size of the array. But I get the following error when I run the code.

#include<stdio.h> #include<stdlib.h> int main() { char *p; p = malloc(10); p = " this is it"; printf("\n%s", p); p = realloc(p, 14); p[11] = 'A'; p[12] = 'B'; p[13] = 'C'; printf("\n %s", p) ; return 0; } 

Output:

 ajay@ajay-K54L :~$ gcc te.c ajay@ajay-K54L :~$ ./a.out *** glibc detected *** ./a.out: realloc(): invalid pointer: 0x000000000040071c *** ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x7e626)[0x7fb111e88626] /lib/x86_64-linux-gnu/libc.so.6(realloc+0x2de)[0x7fb111e8d3ee] ./a.out[0x4005dc] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fb111e2b76d] ./a.out[0x4004d9] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 08:03 3027043 /home/ajay/a.out 00600000-00601000 r--p 00000000 08:03 3027043 /home/ajay/a.out 00601000-00602000 rw-p 00001000 08:03 3027043 /home/ajay/a.out 00e76000-00e97000 rw-p 00000000 00:00 0 [heap] 7fb111bf4000-7fb111c09000 r-xp 00000000 08:03 2100801 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fb111c09000-7fb111e08000 ---p 00015000 08:03 2100801 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fb111e08000-7fb111e09000 r--p 00014000 08:03 2100801 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fb111e09000-7fb111e0a000 rw-p 00015000 08:03 2100801 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fb111e0a000-7fb111fbd000 r-xp 00000000 08:03 2100780 /lib/x86_64-linux-gnu/libc-2.15.so 7fb111fbd000-7fb1121bc000 ---p 001b3000 08:03 2100780 /lib/x86_64-linux-gnu/libc-2.15.so 7fb1121bc000-7fb1121c0000 r--p 001b2000 08:03 2100780 /lib/x86_64-linux-gnu/libc-2.15.so 7fb1121c0000-7fb1121c2000 rw-p 001b6000 08:03 2100780 /lib/x86_64-linux-gnu/libc-2.15.so 7fb1121c2000-7fb1121c7000 rw-p 00000000 00:00 0 7fb1121c7000-7fb1121e9000 r-xp 00000000 08:03 2100760 /lib/x86_64-linux-gnu/ld-2.15.so 7fb1123d2000-7fb1123d5000 rw-p 00000000 00:00 0 7fb1123e5000-7fb1123e9000 rw-p 00000000 00:00 0 7fb1123e9000-7fb1123ea000 r--p 00022000 08:03 2100760 /lib/x86_64-linux-gnu/ld-2.15.so 7fb1123ea000-7fb1123ec000 rw-p 00023000 08:03 2100760 /lib/x86_64-linux-gnu/ld-2.15.so 7ffff08d4000-7ffff08f5000 rw-p 00000000 00:00 0 [stack] 7ffff09ff000-7ffff0a00000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] this is itAborted (core dumped) 

What am I doing wrong with memory allocation? Thanks.

+4
source share
3 answers

It:

 p = " this is it"; /* Does not copy, use strcpy(). */ 

assigns the address of the string literal p , changing it from the address previously returned by malloc() . The pointer passed to realloc() should be:

... previously allocated by malloc (), calloc () or realloc () and not yet freed using free (), otherwise the results are undefined.

Change the assignment to strcpy() , for example, to fix:

 p = malloc(12); /* Increased size. */ if (p) { strcpy(p, " this is it"); char* tmp = realloc(p, 14); /* Store result in temp to avoid potential */ if (!tmp) /* in the event that realloc() fails. */ { free(p); return -1; } p = tmp; /* snip ... */ free(p); /* When 'p' is no longer required. */ } 
+8
source

You overwrite the pointer returned by malloc() with the string:

 p = " this is it"; 

You should use strcpy() to copy the string to the memory pointed to by p :

 strcpy(p, "this is it"); 

Note that this line requires more space than you allocate: these are 10 visible characters, but the lines have a 0-character terminator, so you need at least 11 space characters.

In addition, you must check the return value of both malloc() and realloc() before relying on a valid pointer. If it is NULL , the distribution failed. This is unlikely to take into account your placement sizes, but it is good practice.

+3
source
 char *p = malloc(10); 

allocates a memory block of size 10 and points p to this memory. Then

 p = " this is it"; 

defines a constant string literal and makes p point to read-only memory where this constant string literal is stored. So

 p = realloc(p, 14); 

trying realloc is a read-only memory device that creates undefined behavior.


Instead of assigning the address of a constant string literal p (which also reports a memory leak , since the address of the memory that you are dynamically allocating is lost), you should copy this string using strcpy . Therefore replace this line:

 p = " this is it"; 

with this:

 strcpy(p, " this is it"); 
+2
source

All Articles