1

As far as I know ; In c++ and c delete operator or free() function can know the size of allocated memory from pionter data type and delete can call the destructor automatically.

If the allocated pointer is registered using a kind of singleton static dynamic array which don't use new operator in its mechanism (ie. malloc only) in oveloaded new pointer. this array register void* pointers and take the size of that pointer from overloaded new operator

Ex.

void * operator new (size_t sz) {
  void * m = malloc (sz);
  Dynamic_Array::get_instance()->add(m,sz) ; //registering  pointer
  return m ;
}

so My question is how to use the information about size to release the exact allocated memory that I forget to delete using the destructor of this array.

Ex.

Dynamic_Array::~Dynamic_Array() {
  int index = 0;
  while(index < storage_size) //storage_size: total number of pointers in array 

 /* storage is void** array which  register 
   allocated pointers as void* and use classic memset and memcpy to enlarge*/

    {
      if (storage[index] != NULL) printf("Pointer : %d was not deleted\n", storage[index]);
//how to use delete or free here to delete void* pointer  but with known size of memory
      index ++;
      }
}

Thank you.

youssef
  • 613
  • 4
  • 16
  • 6
    You don't need to know the size. If it was allocated using malloc it can be deallocated using free. The memory manager knows how big the block it allocated is. – Retired Ninja Mar 09 '15 at 02:04
  • but if the I say free(void*) does free know exactly the size of allocated memory? and if I pass C++ object * pointe to void * by cast how can I call delete (void*) "as it will give warning of deleting unkown type (void*)" – youssef Mar 09 '15 at 02:09
  • I mean how to give the array the ownership of that pointer – youssef Mar 09 '15 at 02:11
  • You can't call `delete(void*).` it doesn't exist. You don't need to. You call `free().` – user207421 Mar 09 '15 at 02:11
  • 1
    No.. he can't use free because it could potentially leak since free doesn't call the destructor. He's casting his class pointer to a `void*` and wants to know how to delete the allocated class at that memory address. – Brandon Mar 09 '15 at 02:12
  • @Brandon yes this is another problem – youssef Mar 09 '15 at 02:14
  • @Brandon So he needs to *not* cast it, and call free() from within the destructor, or a custom delete operator method. – user207421 Mar 09 '15 at 02:39
  • You can call free() easily as others have noted, but the real problem is that you will often need to call delete (or the destructor) instead, which needs to know the type to "do the right thing." So, I think your real question is "is there a way that I can store the type of an object in data so that I can cast a pointer void* to that object type appropriately without hard coding it?" I was thinking you could do something with storing a function pointer to a static method of the class somehow, but I don't know how to do a dynamic cast where the code itself doesn't know the type explicitly. – jschultz410 Mar 09 '15 at 04:34
  • Maybe you could make a template wrapper class that inherits from a non-template base class that knows the underlying object's type and has a virtual destructor. Then you could store a pointer to the base class and when you go to deallocate it, you could call delete on the base class, which would "do the right thing" for the type it encapsulates. – jschultz410 Mar 09 '15 at 04:50
  • Nope that won't work because the "top level" new doesn't know the type (if any) being allocated. It's just allocating a bunch of bytes. – jschultz410 Mar 09 '15 at 05:01
  • use of **malloc(3)** or **free(2)** is discouraged in C++. You have **new** and **delete** operators for that. If you call **free(3)** with something acquired with **new** you'll run into trouble. The same as if you call **delete** with something acquired with **malloc(3)** (in case some of these have sense to be done) Constructors/destructors have nothing to do with these. The compiler is what arranges for constructors/destructors to be called, so they will never be called from **malloc(3)** or **free(3)** as these are C functions, not C++. – Luis Colorado Mar 11 '15 at 13:06

2 Answers2

5

As far as I know ; In c++ and c delete operator or free() function can know the size of allocated memory from pionter data type

No. The delete operator calls the free() function; the free() function knows the size from metadata associated with the pointer somehow, for example a length word in the preceding word of memory.

and delete can call the destructor automatically.

Yes.

My question is how to use the information about size to release the exact allocated memory that I forget to delete using the destructor of this array.

You don't need to know. See above.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • `"... the free() function knows the size from metadata associated with the pointer somehow ..."` Can you please elaborate more on this? or give a reference? – zardosht Sep 08 '20 at 18:59
  • Here a related question: https://stackoverflow.com/questions/1518711/how-does-free-know-how-much-to-free – zardosht Sep 08 '20 at 19:07
1

in C,

The free() function uses the data structure in the heap that surrounds the allocated memory.

That data structure includes the real start address of the allocated memory, the address of the prior memory block in the heap, and the address of the next memory block in the heap.

In general, the heap is actually two linked lists.

One is allocated memory and one is free memory.

a malloc operation takes an appropriately sized block from the free linked list and puts it into the allocated memory linked list. This may involve breaking a larger free memory block into two smaller memory blocks, where one is moved to the allocated memory linked list and pointer are adjusted in the free memory list for the new block

A free removes the entry from the allocated memory linked list and puts it into the free linked list.

then if the free linked list contains two adjacent memory blocks, then those two memory blocks are combined into a single/larger memory block.

There are several algorithms that may be used to determine exactly which free area is broken up/moved to the allocated memory list.

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • Your last paragraph makes very little sense. How is `new` returning an address different or "tricky" compared to `malloc` returning an address. C++ also doesn't do garbage collection so I have no idea what the last sentence is trying to say. – Blastfurnace Mar 11 '15 at 13:10
  • C++ can combine adjacent memory blocks when trying to allocate a memory block that is larger than any of the currently available blocks, but less than the sum of the currently available blocks. However, since it is only one of the available algorithms to use, I'll be nice and delete the last paragraph – user3629249 Mar 11 '15 at 15:01
  • Yes, the heap manager can coalesce adjacent free blocks but when you use phrases like "garbage collection" or "move the memory location" it's kind of misleading. It makes C++ memory management sound vaguely like Java. – Blastfurnace Mar 11 '15 at 15:09