I'm not really sure why this is happening but in the code below I made a simple program to help me understand how malloc works. I was basically trying to see how resizing arrays works in term of memory addresses.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
char* buff;
buff = malloc(10);
buff = "hi";
printf("%c\n", buff[0]);
printf("%p\n", &buff[0]);
if (realloc(buff, (size_t) 20) == NULL){
printf("no\n");
exit(1);
}
printf("%p\n", &buff[0]);
return 0;
}
But when I run it, realloc returns NULL. Here it is running with valgrind.
valgrind ./test
==3421== Memcheck, a memory error detector
==3421== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3421== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3421== Command: ./test
==3421==
h
0x400734
==3421== Invalid free() / delete / delete[] / realloc()
==3421== at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3421== by 0x400673: main (in /home/puf311/cs3733/practice/test)
==3421== Address 0x400734 is not stack'd, malloc'd or (recently) free'd
==3421==
no==3421==
==3421== HEAP SUMMARY:
==3421== in use at exit: 10 bytes in 1 blocks
==3421== total heap usage: 2 allocs, 1 frees, 15 bytes allocated
==3421==
==3421== LEAK SUMMARY:
==3421== definitely lost: 10 bytes in 1 blocks
==3421== indirectly lost: 0 bytes in 0 blocks
==3421== possibly lost: 0 bytes in 0 blocks
==3421== still reachable: 0 bytes in 0 blocks
==3421== suppressed: 0 bytes in 0 blocks
==3421== Rerun with --leak-check=full to see details of leaked memory
==3421==
==3421== For counts of detected and suppressed errors, rerun with: -v
==3421== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
As far as I know, the string is malloc'ed, and I definitely didn't free it earlier. So, what's going on here?
reallocreturns the new pointer. If you don't save it, you loose the memory. But remember, ifreallocfails and returnsNULL, the old pointer is still valid, so don't reassign back to the same pointer you pass as argument torealloc.buf = "hi";throws away the pointer that was returned bymallocand replaces it with a pointer to a string literal. You can't pass a pointer to a string literal torealloc. If you want to put the string"hi"into the memory thatmallocreturned, then usestrcpy(buf, "hi");.buff = "hi";you reassign the original pointer returned bymalloc. It's like doingint a = 10; a = 5;and then wondering whyaisn't equal to10anymore.