-1
/*Pointer Array (Dynamic) EXAMPLE*/

int size = 0;
printf("Enter the size of the array you want:\n");
scanf("%d",&size);

int * Dptr = malloc(sizeof(*Dptr)*size);
if(!Dptr)
    return -1;

for(int i=0;i<size;i++)
    Dptr[i]= -7;

printf("Congratulations, you successfully allocated and wrote to a dynamic array.\n");

free(Dptr); //how does it "know" what to deallocate? Is everything getting proprely reclaimed?

Above the a little doodle in C I wrote, I had a question about memory allocation concerning dynamic arrays. At the end I call the free function to deallocate the memory of the array I allocated, but my question is, how does it "know" how much memory to deallocate? Or, is it just deallocating the first int and leaving everything else dangling? If so, what is the proper way to reclaim this memory?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
trashpanda
  • 93
  • 1
  • 13
  • 1
    The implementation of `malloc` and `free` keep info about what has been allocated and what to deallocate. – DeiDei Jan 19 '17 at 18:42
  • 1
    There are many memory allocators that are open source and that you could look at how they work. One way is to allocate a little extra to store the size, and return a pointer to the first byte after the size. The `free` function then looks at a negative offset from the pointer it is passed to find the size. It's not really a detail you need to know unless you want to write your own allocator though. – Some programmer dude Jan 19 '17 at 18:44
  • 2
    The implementation stores the allocated sizes. I believe, it'll usually be stored just before the allocated memory. Some malloc implementations have APIs (it's malloc_usable_size() on linux) to look up the allocated size, given a pointer. – Petr Skocik Jan 19 '17 at 18:44
  • `Or, is it just deallocating the first int and leaving everything else dangling?` That's crazy too. :D – DeiDei Jan 19 '17 at 18:44
  • 2
    That (details remembered internally) is why you must only pass a pointer value to `free` that was allocated (or a copy of the pointer, `free` cannot know any difference). If you pass the pointer returned by `malloc`, then `free` will release all the memory that was allocated. – Weather Vane Jan 19 '17 at 18:44

1 Answers1

2

The free call releases the entire buffer; a single malloc call should correspond to a single free call.

As to how it knows... well, that's going to depend on the implementation. But if you're just looking for peace of mind, consider this:

If the system didn't know how big the buffer was, how would it know where it could start the next dynamic allocation (if you should call malloc again without having freed the first buffer)?

This is all the responsibility of the memory management libraries. It will work in any properly implemented system.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • > If the system didn't know how big... Actually, this does not replies to the OP question, in fact the OP was in doubt about free() leaks memory... :-) – linuxfan says Reinstate Monica Jan 19 '17 at 18:50
  • Sort of, more like I wasn't sure if my use of it was incorrect and leaking memory. I trusted the function, not myself. (; – trashpanda Jan 19 '17 at 18:52
  • 1
    @linuxfan - Wrong. The question specifically asks about whether/how the system knows how much memory to de-allocate, as that's the reason for worrying about potential memory leaks. The broader question about whether it leaks memory had already been covered in my 1st sentence. – Mark Adelsberger Jan 19 '17 at 18:58
  • @MarkAdelsberger It was a joke, but it is not wrong. For a hypotetical broken memory manager, it is possible to allocate memory continuously without remembering the size of the single blocks, and trust the user code when releasemem() is called specifying the amount to free. The free blocks would form a linked list to try before expanding the heap. I even used a mechanism like this, when RAM was very expensive. – linuxfan says Reinstate Monica Jan 19 '17 at 19:06
  • 1
    @linuxfan - Wrong again. First of all, you originally claimed my answer didn't address the original question. Yet it did. Secondly, your ability to imagine a memory manager (which you admit wouldn't work correctly anyway) has no relevance to anything. Sorry your attempted pedantry wasn't rewarded here, but that won't change. – Mark Adelsberger Jan 19 '17 at 19:31
  • @MarkAdelsberger I didn't criticize the answer, only the sentence beginning with "If the system didn't know...". It is redundant AND WRONG. Take a look at the many memory managers around. Ask yourself why pascal freemem() accepts a SIZE parameter, ignored nowadays, but useful when ram was little. I am sorry for you, take it easy. I was joking but I said the truth. – linuxfan says Reinstate Monica Jan 19 '17 at 19:41