4

Possible Duplicate:
How to get memory block length after malloc?

If I have a pointer, is it possible to learn how many bytes were allocated by new? When I googled I found a solution for Windows: _msize() and for Mac: malloc_size(). But nothing for Linux.

And if not, does anybody know why is it hidden from a programmer? delete should definitely know such info.

Update:

As far as I know, if I have this code:

 class A {   
   ~A() {}
   int m_a; 
 }; 
 class B : public A {
   ~B() {}
   int m_b; 
 };

 int main() {   A * b = new B();   delete b;   return 0; }

Destructor of A will be called, but still all the memory allocated by new will be freed. This means that it can be somehow computed knowing only the pointer. So what is the reason for hiding it from a programmer?

Community
  • 1
  • 1
Shamdor
  • 3,019
  • 5
  • 22
  • 25
  • 3
    You'll get at least as many bytes as you asked for. Why do you need more detail than that? – John3136 Sep 21 '12 at 05:43
  • delete operator does not need to know it.It simply instruct memory manager to free block.Basically sizeof() will not report exact same value on Windows due to heap sentinels, maybe similar on linux, read kernel docs about memory management and libc implementation of new operator – rkosegi Sep 21 '12 at 05:45
  • @rkosegi sizeof is not even useful here. It returns the size of the pointer (4 or 8 bytes) and not the size of the underlying allocated memory chunk. You'd better grab a C pointers tutorial *now*. –  Sep 21 '12 at 05:49
  • @H2CO3 , I know, I mean if you do new(SOME_STRUCT) and compare to sizeof(SOME_STRUCT). – rkosegi Sep 21 '12 at 06:03
  • @H2CO3 new and malloc are different, because malloc have record the memory size and new do not – Torsten Robitzki Sep 21 '12 at 07:48
  • @TorstenRobitzki I don't quite get what you are talking about. "Malloc have record the memory size" - even if it does, that's implementation detail, and should not be relied upon. "and new do not" - well, if we dig into the implementation details: one, how do you know it doesn't? Tow, new is usually implemented using malloc... –  Sep 21 '12 at 07:52
  • @H2CO3 All I'm saying is: 'there is a fundamental difference between both, so this question can't be a duplicate'. – Torsten Robitzki Sep 21 '12 at 09:33
  • @John3136: The usual example is an I/O buffer. Sometimes you want the buffer to be an exact multiple of the underlying block size (e.g. of a file system or a TCP/IP packet), which you don't necessarily know but if you do fair enough. Otherwise, you'd like to use all the memory the allocator gave you, but there's no portable way so you don't. Another example is exponential array growth, you'd do fewer reallocations if you always used the over-allocation. More likely, though, this question is asked by someone who used to know what size they allocated, but didn't record it. – Steve Jessop Sep 21 '12 at 09:34
  • @John3136 Do you mean, I pass a buffer to a function plus it's size; 100 for example and the function returns that 101 bytes where written? – Torsten Robitzki Sep 21 '12 at 20:10
  • Why is this closed as a duplicate when there are arguments, why this is _not_ a duplicate? Can someone of those who voted for this being a duplicate explain, what new and malloc have in common and more interesting in what respect they differ? – Torsten Robitzki Sep 21 '12 at 22:46

6 Answers6

5

Unfortunately, there is no portable way of obtaining the number of bytes allocated by new and malloc. There are a number of reason why this is the case:

  • On some platforms, delete and free do nothing at all. As such, they don't need to store size information. This is surprisingly common in embedded platforms; it lets you use C or C++ code written for other platforms unchanged, as long as you don't do too much allocation.
  • Even on more common platforms, the system may allocate a different number of bytes than you ask for. Typically your allocation will be aligned to some larger size - possibly much larger than your original request. The storage metadata might also be stored in a very slow data structure - you wouldn't want to be taking locks and accessing a hash table in time-critical code.

As portable languages, C and C++ can't offer a feature that won't be available (or well-defined, or reasonably fast) on every platform. That's why this is not available on C++. That said, you don't need this - C++ offers std::vector, which does track the size of your allocation, or std::string which takes care of all of those details for you.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
4

new, malloc, calloc and all the other heap related allocations in the language (yes, there are many more than those) will allocate at least the amount of memory you requested. They may allocate more (and in general they will allocate more).

There is no portable way to know how much they allocated. In fact there is no way at all unless you know exactly what heap manager you are using.

You also need to distinguish allocated memory in the sense of memory that you may access safely from the returned pointer (that's what malloc_size returns on macs and probably what _msize returns on windows) from actual memory that is 'taken away from the heap' because of the allocation (which includes bookkeeping information which may or may not be adjacent to the memory block you allocated and may or may not be the same for same-sized allocations).

Analog File
  • 5,280
  • 20
  • 23
1

Q: So can I query the malloc package to find out how big an allocated block is?

A: Unfortunately, there is no standard or portable way. (Some compilers provide nonstandard extensions.) If you need to know, you'll have to keep track of it yourself.

C-FAQ

Laser
  • 6,652
  • 8
  • 54
  • 85
1

What the new operator does is it invokes a constructor so the size of the allocation depends on the type whose constructor you're invoking.

E.g.

class A
{
private:
    int* x;
public:
    A() { x = new int [100]; }
};

Will allocate sizeof(int) * 100 but you cannot know that if the implementation of the A is hidden from you.

If you perform yourself:

int * x = new int [100];

Then you know how much you have allocated because of have access to sizeof(primitive).

Furthermore the delete operator invokes a destructor so for complex objects it again does not need to know the size of the allocated memory as the responsibility for freeing the memory fully and correctly is entirely delegated to the programmer.

So there isn't a straight forward answer here.

Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100
  • But what about int * x = NULL, you also allocate size for pointer. so sizeof(int)*NULL not work here. – Laser Sep 21 '12 at 05:57
  • Yes, but I want to know it having only the pointer in real time. – Shamdor Sep 21 '12 at 06:04
  • @Pepelac the question is about the new operator not about assigning pointers to the nullptr. – Konstantin Dinev Sep 21 '12 at 06:18
  • @KonstantinDinev But i think you allocated more that just "sizeof(type)*count elements" i mean size will be some_size+pointer_size. Am i right? – Laser Sep 21 '12 at 07:43
  • @Pepelac actually we can disregard the pointer size (you are correct we still store this and the size of it depends on the architecture: 32bit vs. 64bit, etc.) because it's constant, the memory that new operator is allocating is really more significant. – Konstantin Dinev Sep 21 '12 at 07:46
1

In addition to the answers above: In some situations, the size that have to be allocated and deallocated are known at compile time and it would be a complete waist of memory, to record the size somewhere.

In cases where the static type is equal to the dynamic type, the memory to be deallocated can be determined by the type.

In cases, where the static type is not equal to the dynamic type, the deleted objects class has to have a virtual destructor. This destructor can be used to deallocate the right size of memory.

When allocating an array, the size of the array is usually attached to that array in a implementation dependent manner and the size to be deallocated can be determined by the type of the elements and the size of the array.

Torsten Robitzki
  • 3,041
  • 1
  • 21
  • 35
0
 X x=new X()

here it depend on the size of class i.e. the number of variables class contains.

int x = new int [100];

here it depend on how many elements u r going to allocate.suppose, int takes 2 byte,then here it takes 200 bytes.
shortly, we can say that, it depend on the data type, for which u r using new operator

Ravindra Bagale
  • 17,226
  • 9
  • 43
  • 70
  • Actually if int takes 2 bytes the second example will allocate _at least_ 200 bytes. On most platforms it will allocate more. – Analog File Sep 21 '12 at 07:17
  • no,it allocates only 200 bytes on windows platform
    .in unix int data type takes 4 bytes. i.e.for 100 elements it takes 400 bytes.
    – Ravindra Bagale Sep 21 '12 at 07:54
  • It really depends on how you define "allocated bytes". See my answer. The number of bytes you can access from that pointer (which is what `_msize()` returns) is likely 200. But the actual space used by that allocated block in memory is very very likely to be more than that (and on most platforms it is). – Analog File Sep 21 '12 at 10:20
  • @Analog File- if it allocates more memory,then what is use of data types. – Ravindra Bagale Sep 21 '12 at 16:42
  • I do not understand your question. It allocates more memory for bookkeeping. Either adjacent to your block or somewhere else the allocator needs to know if a specific block is allocated or free, how large it is, how to walk the block chain etc. Read the source code of a heap manager and you'll see what it really does. – Analog File Sep 22 '12 at 02:22