-1

I created array with 10 integer size using malloc. I added values to the elements. Then, I reallocated it to 200 bytes into newArr. And then I reallocated newArr into newArr2 with size of 10 integers again. Code:

void main(){

    int i, *arr = (int *)malloc(10* sizeof(int));

    for(i=0; i<10; i++){
        arr[i] = i;
    }

    int *newArr = (int *)realloc(arr, 200);

    int *newArr2 = (int *)realloc(newArr, 10* sizeof(int));

}

How should I use free to remove all the allocated memory here? I'm getting error while clearing all of them.

Edit: As per the accepted answer the old memory should've been cleared but it didn't. I was able to access memory and was able to change value on old address.

Kshitij Kumar
  • 350
  • 4
  • 17

2 Answers2

3

From my point of view, when you use malloc or realloc you're changing the memory reference, so, if you call realloc on a variable you are freeing the old space used and allocate new space, copying the old data to the new memory position, so, in your example, arr doesn't hold a valid memory address after first realloc. The same thing happen on newArr

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
Max Forasteiro
  • 382
  • 2
  • 13
  • But when I read values on those old address, it is showing the same old value. Is it normal? I'll check few more things. – Kshitij Kumar Dec 26 '17 at 14:20
  • I was able to handle arr even after reallocating. I changed value, checked address and was able to do everything in runtime. – Kshitij Kumar Dec 26 '17 at 14:34
  • Max, note that `realloc` _may_ return a new address, but it doesn't have to, for example when there was sufficient free memory after the currently allocated memory it will simply expand the allocation. In all cases, it is important to mention that there may be only _one_ call to `free` to free the memory. – Paul Ogilvie Dec 26 '17 at 14:39
  • Even after it's relocating completely to a new address, it is not freeing the old array memory. It's still accessible and contains value. I think the only way to clear the memory completely is by comparing old and new address and then freeing them accordingly. – Kshitij Kumar Dec 26 '17 at 14:43
  • `The content of the memory block is preserved up to the lesser of the new and old sizes, even if the block is moved to a new location. If the new size is larger, the value of the newly allocated portion is indeterminate. ` from http://www.cplusplus.com/reference/cstdlib/realloc/ so, it's true – Max Forasteiro Dec 26 '17 at 15:14
  • And yes, it not free the old portion of memory (in case of reallocating the portion) – Max Forasteiro Dec 26 '17 at 15:15
2

realloc is basically malloc with the new size, memmove the data to the new block and free the old one. (But implementation can optimize this process because they've got more information they can use, like just extending the current allocated block, producing the same pointer)

So the pointers arr and newArr are invalid and shouldn't be accessed anymore because they might have been freed, so the pointer in newArr2 is the current one and valid, if the previous allocations didn't fail. So free(newArr2) is the correct answer.

Sure, you might access the memory from the old pointers, but it isn't guaranteed because it might've been allocated and overwritten for a different purpose or you might just be lucky to get the same pointer back from realloc (because from eg. the optimization above). It's just undefined behavior when accessing freed memory.

Source on reddit

Neui
  • 322
  • 4
  • 7
  • Important to add here, I think you missed to point out properly that your pointer does not get `free()`d if any one call to `realloc()` failed; that is, if `newArr` turns out `NULL`, you have to still `free(arr)` and if `newArr2` turns out `NULL` you have to still `free(newArr)` respectively. – mar77i Jan 06 '18 at 00:09