C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Why can't I get the size of an array allocated with new []?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Antonio Maiorano
Guest





PostPosted: Wed Aug 18, 2004 12:10 pm    Post subject: Why can't I get the size of an array allocated with new []? Reply with quote



Hey everyone,

My friend asked me a question and I had no clue how to answer it. So I
figured I'd see what you all have to say. Here is his question:

Say we have the following:

class MyClass
{
public:
MyClass() {}
~MyClass() {}

int myInt;
float myFloat;
};

MyClass* MyAllocator (int iNum)
{
return new MyClass[iNum];
}

void MyFreer (MyClass*& array)
{
delete []array;
}

So, as we all know, this is perfectly OK C++ code, and in the MyAllocator
function we will allocate iNum items (and call the constructor for each),
and in the MyFreer function we will free all the memory and call the
destructor for each once again. So, for this to happen, the C++ compiler
must keep memory somewhere of how many elements the array returned by
MyAllocator contains. Why is it that we don't have access to this (or do
we?)? IE why don't we have a size() operator that returns how big an array
is. One could argue that calling this on a pointer that's not an array
would cause problems, but wouldn't calling delete [] on the same pointer
also cause problems?

--
Antonio Maiorano
Software Engineer, Electronic Arts
E-Mail: m a i o r a n o AT v i d e o t r o n DOT c a



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Kai-Uwe Bux
Guest





PostPosted: Wed Aug 18, 2004 6:32 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote



Antonio Maiorano wrote:

Quote:
Hey everyone,

My friend asked me a question and I had no clue how to answer it. So I
figured I'd see what you all have to say. Here is his question:

Say we have the following:

class MyClass
{
public:
MyClass() {}
~MyClass() {}

int myInt;
float myFloat;
};

MyClass* MyAllocator (int iNum)
{
return new MyClass[iNum];
}

void MyFreer (MyClass*& array)
{
delete []array;
}

So, as we all know, this is perfectly OK C++ code, and in the MyAllocator
function we will allocate iNum items (and call the constructor for each),
and in the MyFreer function we will free all the memory and call the
destructor for each once again. So, for this to happen, the C++ compiler
must keep memory somewhere of how many elements the array returned by
MyAllocator contains.

This is not true if the destructor is trivial and the calls to the
destructor are optimzed away. In that case, the compiler only needs to keep
track of the size of the memory chunk that was allocated for the array.
This chunk will usually be some multiple of 16 bytes or even more
wastefull. Thus it might not be enough to deduce the length of the array.



Best

Kai-Uwe Bux


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Arkadiy Vertleyb
Guest





PostPosted: Thu Aug 19, 2004 12:10 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote



"Antonio Maiorano" <do (AT) not (DOT) use> wrote

Quote:
Say we have the following:

class MyClass
{
public:
MyClass() {}
~MyClass() {}

int myInt;
float myFloat;
};

MyClass* MyAllocator (int iNum)
{
return new MyClass[iNum];
}

void MyFreer (MyClass*& array)
{
delete []array;
}

So, as we all know, this is perfectly OK C++ code, and in the MyAllocator
function we will allocate iNum items (and call the constructor for each),
and in the MyFreer function we will free all the memory and call the
destructor for each once again. So, for this to happen, the C++ compiler
must keep memory somewhere of how many elements the array returned by
MyAllocator contains. Why is it that we don't have access to this (or do
we?)? IE why don't we have a size() operator that returns how big an array
is. One could argue that calling this on a pointer that's not an array
would cause problems, but wouldn't calling delete [] on the same pointer
also cause problems?

Well, this is not the only thing the C++ compiler knows about, but
wouldn't tell us. For example:

1) Is this particular type a pointer?
2) Is class X derived from class Y?
3) What is the return type of this particular expression?
4) Does class X have typedef (or nested class) Y?

etc.

This has created lots of fun (and I mean it!) for people inventing
ways to indirectly extract this information.

In your case, however, you can just store the iNum somewhere and use
it. Or use std::vector<>, which does have the size() operator.

Regards,

Arkadiy

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Julien Lamy
Guest





PostPosted: Fri Aug 20, 2004 12:20 am    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

Antonio Maiorano wrote:
Quote:
Hey everyone,

My friend asked me a question and I had no clue how to answer it. So I
figured I'd see what you all have to say. Here is his question:

Say we have the following:

class MyClass
{
public:
MyClass() {}
~MyClass() {}

int myInt;
float myFloat;
};

MyClass* MyAllocator (int iNum)
{
return new MyClass[iNum];
}

void MyFreer (MyClass*& array)
{
delete []array;
}

So, as we all know, this is perfectly OK C++ code, and in the MyAllocator
function we will allocate iNum items (and call the constructor for each),
and in the MyFreer function we will free all the memory and call the
destructor for each once again. So, for this to happen, the C++ compiler
must keep memory somewhere of how many elements the array returned by
MyAllocator contains. Why is it that we don't have access to this (or do
we?)? IE why don't we have a size() operator that returns how big an array
is. One could argue that calling this on a pointer that's not an array
would cause problems, but wouldn't calling delete [] on the same pointer
also cause problems?


Actually, such an operator exists : it's sizeof. To quote the standard
(5.3.3-2) :
"When applied to an array the result [of the sizeof operator] is the
total number of bytes in the array. This implies that the size of an
array of n elements is n times the size of an element."

So, sizeof(array)/sizeof(MyClass) yields the number of elements in the
array.

--
Julien Lamy

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Fri Aug 20, 2004 1:38 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

In article <cg1k6i$nu2$1 (AT) news (DOT) u-strasbg.fr>, Julien Lamy
<julien.NOSPAMlamy (AT) ircad (DOT) u-strasbg.fr> writes
Quote:
Actually, such an operator exists : it's sizeof. To quote the standard
(5.3.3-2) :
"When applied to an array the result [of the sizeof operator] is the
total number of bytes in the array. This implies that the size of an
array of n elements is n times the size of an element."

So, sizeof(array)/sizeof(MyClass) yields the number of elements in the
array.

Which in the context of:

mytype * array = new mytype[n];

will most likely return 0.

The mechanism you propose is useless for anything other than for a
static array whose definition is in scope.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Arkadiy Vertleyb
Guest





PostPosted: Sat Aug 21, 2004 3:33 am    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

Julien Lamy <julien.NOSPAMlamy (AT) ircad (DOT) u-strasbg.fr> wrote
Quote:
Antonio Maiorano wrote:
MyClass* MyAllocator (int iNum)
{
return new MyClass[iNum];
}

void MyFreer (MyClass*& array)
{
delete []array;
}

Actually, such an operator exists : it's sizeof. To quote the standard
(5.3.3-2) :
"When applied to an array the result [of the sizeof operator] is the
total number of bytes in the array. This implies that the size of an
array of n elements is n times the size of an element."

So, sizeof(array)/sizeof(MyClass) yields the number of elements in the
array.

sizeof() is a compile-time thing and will not work in this context,
where the memory is allocated at runtime. If you try to do something
like:

sizeof(MyAllocator(10))

it will just evaluate to 4(the size of a pointer).

Regards,
Arkadiy

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dave Harris
Guest





PostPosted: Sat Aug 21, 2004 3:59 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

[email]jkherciueh (AT) gmx (DOT) net[/email] (Kai-Uwe Bux) wrote (abridged):
Quote:
This is not true if the destructor is trivial and the calls to the
destructor are optimzed away. In that case, the compiler only needs to
keep track of the size of the memory chunk that was allocated for the
array. This chunk will usually be some multiple of 16 bytes or even
more wastefull. Thus it might not be enough to deduce the length of the
array.

Alternatively, it can store the size of the array and deduce the size of
the memory block from that. During deallocation it can do the same
rounding up to a multiple of 16 bytes it did during allocation.

I think the main reason is historical and/or for interaction with C
libraries. Operator new() is often implemented in terms of malloc(), and
malloc() knows only of memory blocks.

-- Dave Harris, Nottingham, UK

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andrea Griffini
Guest





PostPosted: Sun Aug 22, 2004 3:29 am    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

On 21 Aug 2004 11:59:19 -0400, [email]brangdon (AT) cix (DOT) co.uk[/email] (Dave Harris) wrote:

Quote:
Alternatively, it can store the size of the array and deduce the size of
the memory block from that. During deallocation it can do the same
rounding up to a multiple of 16 bytes it did during allocation.

You can't because the allocator is not told about the array size,
but just about the memory needed.

Andrea

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dave Harris
Guest





PostPosted: Sun Aug 22, 2004 10:48 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

[email]agriff (AT) tin (DOT) it[/email] (Andrea Griffini) wrote (abridged):
Quote:
Alternatively, it can store the size of the array and deduce the
size of the memory block from that. During deallocation it can
do the same rounding up to a multiple of 16 bytes it did during
allocation.

You can't because the allocator is not told about the array size,
but just about the memory needed.

The idea is to have the same information available at deallocation as is
available at allocation, at any given level of the memory system. So at
the object level we know the size of each object and the number of them.
We can multiple those together to give the minimum block size and pass
that to the allocator. The allocator then rounds up to get the actual
block size. The allocator doesn't need to store that size because it can
be recomputed from the data it is passed.

This isn't how C++ is designed, but I believe it would be a viable design
for some new low-level language. It would avoid the inefficiency of C++
where-by the size is often effectively stored 3 times: once by malloc() as
the size of the memory block; once by the new expression as the count of
destructors that need to be run; once by the application as the count of
objects in the array (which is the same as the count of destructors, which
C++ does not make available).

Given that it claims to be a low-level language, the memory architecture
of C++ is surprisingly inefficient.

-- Dave Harris, Nottingham, UK

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dr Pizza
Guest





PostPosted: Mon Aug 23, 2004 10:29 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

"Antonio Maiorano" <do (AT) not (DOT) use> wrote

Quote:
Why is it that we don't have access to this (or do
we?)?
We don't.


Why not?

Because C++ follows the fine (@_@) C tradition of inadequate memory
primitives.

The runtime must know how many objects are in an allocated block (so
it can call the right number of destructors) and in practice also
knows how big a block really is (in principle I think new doesn't
strictly need this, but malloc does, because malloc has realloc, so
it's no real hardship for new to have it either).

But there's no (standard) mechanism for accessing this information.
Non-standard facilities exist; for example, VC++ permits one to know
the true size of a block (and hence know ahead of time whether a
realloc will be in-place or not) with its _msize() function; it allows
a block to be resized in-place with its _expand() function.

If C++ provided access to these functions along with something like an
arraysize() function (to say how many objects have been allocated into
a block) then we could do a number of useful things, like provide a
"renew" (by analogy with realloc()) and a smarter version of vector
(which only reallocated when it *really* had to rather than simply
when it *thought* it had to).

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Antonio Maiorano
Guest





PostPosted: Mon Aug 23, 2004 10:30 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

"Dave Harris" <brangdon (AT) cix (DOT) co.uk> wrote in message
<snip>
Quote:
This isn't how C++ is designed, but I believe it would be a viable design
for some new low-level language. It would avoid the inefficiency of C++
where-by the size is often effectively stored 3 times: once by malloc() as
the size of the memory block; once by the new expression as the count of
destructors that need to be run; once by the application as the count of
objects in the array (which is the same as the count of destructors, which
C++ does not make available).

So then coming back to my original question, according to you there is no
good reason for which C++ does not make the number of allocated elements
available? If the new expression stores the number of elements in order to
call the proper number of destructors, then the language could allow one to
retrieve this number, right?

The only reason that I can see for the language not allowing the number of
elements to be retrieved is for when there are no destructors that need to
be called, as is the case for basic types (int, float, etc.). In these
cases, only the memory block size need be stored, not the number of
elements. Then again, if only the allocation size is stored (w/o the
padding), then getting the number of elements would simply result in
MemBlockSize / sizeof(ElementType), which would work for both basic types
and class types.

What do you think?


--
Antonio Maiorano
Software Engineer, Electronic Arts
E-Mail: m a i o r a n o AT v i d e o t r o n DOT c a



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Michiel Salters
Guest





PostPosted: Tue Aug 24, 2004 10:33 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

[email]brangdon (AT) cix (DOT) co.uk[/email] (Dave Harris) wrote in message news:<memo.20040822125703.1900B (AT) brangdon (DOT) m>...

Quote:
This isn't how C++ is designed, but I believe it would be a viable design
for some new low-level language. It would avoid the inefficiency of C++
where-by the size is often effectively stored 3 times: once by malloc() as
the size of the memory block; once by the new expression as the count of
destructors that need to be run; once by the application as the count of
objects in the array (which is the same as the count of destructors, which
C++ does not make available).

Given that it claims to be a low-level language, the memory architecture
of C++ is surprisingly inefficient.

You can't say this of C++, only of implementations. Any implementation
is free to optimize this, if you can't detect it. After all, the
implementation can rely on implementation-specific tricks (including
reading outside the memory returned by malloc)
Furthermore, you can't even say that malloc stores the size of the
memory block. There are enough allocators that don't store sizes for
small blocks, and with 64-bits address spaces it becomes even easier
(you can spare 2 bits in the address space to differentiate 4 pools)

Regards,
Michiel Salters

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Joshua Lehrer
Guest





PostPosted: Tue Aug 24, 2004 10:36 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

[email]drpizza (AT) gmail (DOT) com[/email] (Dr Pizza) wrote in message news:<623e062b.0408230558.2c749131 (AT) posting (DOT) google.com>...
Quote:
The runtime must know how many objects are in an allocated block (so
it can call the right number of destructors)

Only if the type has a destructor. On our platform, 4(8?) extra bytes
are requested if the type has a destructor. The count is stored, then
the pointer is incremented over the count and returned.

Thus, an array_count would be easily implemented for arrays of types
with destructors, but would add extra, unnecessary overhead, for
arrays of types without.

joshua lehrer
factset research systems
NYSE:FDS

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dr Pizza
Guest





PostPosted: Wed Aug 25, 2004 9:44 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

[email]usenet_cpp (AT) lehrerfamily (DOT) com[/email] (Joshua Lehrer) wrote in message news:<31c49f0d.0408240621.1db57148 (AT) posting (DOT) google.com>...
Quote:
Thus, an array_count would be easily implemented for arrays of types
with destructors, but would add extra, unnecessary overhead, for
arrays of types without.

It is only unnecessary overhead in those few cases where one needs no
knowledge of the length of the array. In _most_ code the length will
be maintained _in_code_ anyway. As such, moving it to the runtime
would impose no additional overhead, it would simply move the
maintenance of that overhead to the runtime, where it belongs.

In the case of the primitive, there's no duplication, but there is
inconvenience (because the length must be passed to functions
independently of the array itself).

In this case of the class with d-tor, added to this inconvenience
there's flat out duplication (because the length must be known to the
runtime anyway).

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dave Harris
Guest





PostPosted: Wed Aug 25, 2004 10:07 pm    Post subject: Re: Why can't I get the size of an array allocated with new Reply with quote

[email]do (AT) not (DOT) use[/email] (Antonio Maiorano) wrote (abridged):
Quote:
So then coming back to my original question, according to you there is
no good reason for which C++ does not make the number of
allocated elements available?

As I said earlier, I believe the reason is because operator new() is
expected to be a layer on top of malloc(). Whether that is a good reason,
I don't know. It may have good historical justification.

Given that the count can't be used by malloc(), nor for destructors in
some cases (and which cases depends on how smart the compiler is), to
store the count always would sometimes be an unnecessary overhead. It's
only acceptable if having the count in the array allows us to avoid having
the count in malloc().

-- Dave Harris, Nottingham, UK

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.