malloc size

H

hotadvice

so finally
1.not returning 0 implies at least the size that was asked is allocated
2.sizeof(*p) gives u th e size

so shall we say pack up
 
H

hotadvice

so finally
1.not returning 0 implies at least the size that was asked is allocated
2.sizeof(*p) gives u th e size

so shall we say pack up
 
E

Eric Sosman

hotadvice said:
so finally
1.not returning 0 implies at least the size that was asked is allocated

Correct.
2.sizeof(*p) gives u th e size

Incorrect (or correct only sometimes, by coincidence).
so shall we say pack up

Surely -- but on the evidence, I'd suggest not packing
up your C textbook quite yet ...
 
K

Keith Thompson

hotadvice said:
so finally
1.not returning 0 implies at least the size that was asked is allocated
Yes.

2.sizeof(*p) gives u th e size

so shall we say pack up

You posted that followup 3 times.

No, sizeof(*p) doesn't give you (that's "you", not "u"; we prefer to
avoid cutesy abbreviations here) the size allocated, it gives you the
size of a single object of the type p points to.

Given:

ptr = malloc(some_size);

there is no portable way, given the value of ptr, to determine the
number of bytes actually allocated. You can determine the number of
bytes *requested*, but only by keeping track of it yourself.

Presumably the system keeps track of the number of bytes actually
allocated (so free() knows what to do), but there's no portable way to
ask the system for this information. If you need to know, your best
bet is to redesign your algorithm so you *don't* need to know.
 
H

Howard Hinnant

Keith Thompson said:
Given:

ptr = malloc(some_size);

there is no portable way, given the value of ptr, to determine the
number of bytes actually allocated. You can determine the number of
bytes *requested*, but only by keeping track of it yourself.

Presumably the system keeps track of the number of bytes actually
allocated (so free() knows what to do), but there's no portable way to
ask the system for this information. If you need to know, your best
bet is to redesign your algorithm so you *don't* need to know.

Well put.

Just fyi, there is a proposal before the C committee which includes a
portable way to get this information:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1085.htm

This proposal, with alternate __function_names, is now shipping from
Metrowerks for those platforms where we supply the C library. This
functionality is also being used in the std::C++ library to optimize
template classes such as vector in some specialized circumstances.

-Howard
 
M

mojozoox

Let me assume it done somewhere in a library and im using it... then
how do i know... ???

mojo
 
T

thesushant

the size requested will be allocated , if that size is not available
then malloc will fail. and u can know the size from the arguments of
malloc and if succesful only that size will be allocated..
 
C

CBFalconer

Howard said:
.... snip ...

Just fyi, there is a proposal before the C committee which includes a
portable way to get this information:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1085.htm

This proposal, with alternate __function_names, is now shipping from
Metrowerks for those platforms where we supply the C library. This
functionality is also being used in the std::C++ library to optimize
template classes such as vector in some specialized circumstances.

As proposed it has a fatal flaw. It requires an xxx_malloc() call
to return the actual size allocated via an auxiliary parameter, but
specifies that it must be 0 for a 0 size request. This fouls up
the systems that need a minimum allocation size for one reason or
another.

In addition the user often wants space for some form of array. The
possible overage is likely to be useless since it won't hold a
complete item. The possibility for programmer error boggles the
mind.
 
K

Keith Thompson

mojozoox said:
Let me assume it done somewhere in a library and im using it... then
how do i know... ???

What is done somewhere in a library? How do you know what?

We can't figure out what you mean if you don't provide any context.

(I took a look at the article you were replying to, but I didn't see
any questions there that haven't already been answered in this
thread.)
 
K

Keith Thompson

the size requested will be allocated , if that size is not available
then malloc will fail. and u can know the size from the arguments of
malloc and if succesful only that size will be allocated..

Please don't top-post.

In fact, a successful malloc() can, and often does, allocate more
bytes than were requested. (It's common for the size to be rounded up
to a multiple of some block size, or to a power of 2.) But the
language provides no portable way to find out how many bytes were
actually allocated.
 
M

Mark McIntyre

Let me assume it done somewhere in a library and im using it... then
how do i know... ???

How do you know what? Please retain some context when posting, and remember
not everyone has read the thread from the start.
 
H

Howard Hinnant

Thank you for your comments. I am most open and interested in improving
this proposal in any way possible.
As proposed it has a fatal flaw. It requires an xxx_malloc() call
to return the actual size allocated via an auxiliary parameter, but
specifies that it must be 0 for a 0 size request. This fouls up
the systems that need a minimum allocation size for one reason or
another.

It is specified only that request_malloc return 0,0 given a 0 size
request. This behavior is trivial to implement on any system. Indeed
the proposal shows a portable implementation.

It is not proposed that malloc must return 0 for a 0 size request. Nor
is it required that sizeof_alloc(malloc(0)) return 0.

However I would gladly change the proposal to require that
request_malloc(0, 0) return non-null on success. My intent here is that
request_malloc have well defined and portable behavior for 0-sized
requests, in contrast to the current behavior for malloc(0) which is
implementation defined. I see no motivation for malloc(0) to be
implementation defined except for (non-portable) backwards
compatibility. And request_malloc has no backwards compatibility
concerns.
In addition the user often wants space for some form of array. The
possible overage is likely to be useless since it won't hold a
complete item. The possibility for programmer error boggles the
mind.

If the sizeof(array-element) < the system alignment / 2, there is a good
chance that the overage will hold a complete item. If it is >= the
system alignment / 2 then I agree that the overage is likely to be
useless. Ignoring that this extra memory exists (when it can be
utilized) doesn't seem logical to me.

As for the possibility for programmer error, I agree that one must
always design interfaces and behavior so that the library is as safe as
possible while still providing the needed functionality. I'm currently
at a loss as how to lesson the dangers you perceive, while still
providing this useful functionality.

Perhaps a future rewrite of this proposal will use a non-char-sized
array as an example. This might better demonstrate how to take
advantage of the extra memory:

void
construct_int_array(int_array* array, size_t size)
{
array->data = 0;
array->size = array->capacity = 0;
if (size)
{
size_t size_received;
array->data = request_malloc(size*sizeof(int), &size_received);
size_received /= sizeof(int); // mind boggling error prone?
if (array->data == 0)
on_error(size_received);
array->capacity = size_received;
array->size = size;
}
}

It seems no more error prone to me than having to adjust your requested
size by the size of your element.

-Howard
 
K

Kelsey Bjarnason

so finally
1.not returning 0 implies at least the size that was asked is allocated
2.sizeof(*p) gives u th e size

No.

int *ptr = malloc( 100 * sizeof(int) );
size_t s = sizeof( *ptr );

s does _not_ equal 100*sizeof(int), it equals the size of *one* int.
 
C

CBFalconer

Howard said:
.... snip ...


It is specified only that request_malloc return 0,0 given a 0 size
request. This behavior is trivial to implement on any system.
Indeed the proposal shows a portable implementation.

It is not proposed that malloc must return 0 for a 0 size request.
Nor is it required that sizeof_alloc(malloc(0)) return 0.

You have specified that request_malloc is shorthand for a sequence
involving malloc and sizeof_alloc. The response cannot be
different, and should not, because such differences create major
confusion.

One system that I created changes all 0 size requests to 1. You
can see the system on my pages, download section, nmalloc.zip. The
reason is that once the allocation is freed it has to go into the
appropriate free list, and needs further links. The actual (now
unused) allocation space (rounded up) can supply this, for a
non-zero size.

Lying back to the user about the actual size defeats the whole
purpose of the arrangement, which is to allow expansion without
system calls. In nmalloc, if you request 0 you will actually get
at least ALIGN bytes (which happens to be 8), possibly more if a
residue is too small to be of use in forming another allocation.

So malloc(0) will normally return non-NULL, and as many as 32 bytes
may be available in my system. For that package at least 8 bytes
will be available. For malloc in general, 0 bytes may be
available. After all, a void* points to void.
 
H

Howard Hinnant

CBFalconer said:
You have specified that request_malloc is shorthand for a sequence
involving malloc and sizeof_alloc. The response cannot be
different, and should not, because such differences create major
confusion.

You are right that the proposal summarizes:
This call is intended to encapsulate a call to malloc and a call to
sizeof_alloc into a single function.

Then the postcondition goes on to state exactly what request_malloc
does, and it may be different for the 0 requested size case (depending
upon how malloc is implemented).

Thank you for pointing out this contradiction. If I get a chance to
rewrite this proposal, I will try to correct that.

The only difference I wish to see between malloc and request_malloc for
zero-sized requests is portable behavior. The behavior of malloc(0)
isn't portable and I wish for the behavior of request_malloc(0,0) to be
portable. That should've been made clear in the proposal.
One system that I created changes all 0 size requests to 1.

You
can see the system on my pages, download section, nmalloc.zip.

Thank you for the link.
The
reason is that once the allocation is freed it has to go into the
appropriate free list, and needs further links. The actual (now
unused) allocation space (rounded up) can supply this, for a
non-zero size.

Yet even though your malloc(0) always returns non-null, free(0) must
still respond appropriately (as yours does modulo an optional? warning).

From 7.20.3.2p2:
If ptr is a null pointer, no action occurs.
Lying back to the user about the actual size defeats the whole
purpose of the arrangement, which is to allow expansion without
system calls.

I have no desire for the proposed interface to lie to the client. I
wish for the interface to be portable. malloc(0) is not. It may return
0, or it may not. From 7.20.3p1:
If the size of the space requested is zero, the behavior is
implementation defined: either a null pointer is returned, or the behavior is
as if the size were some nonzero value, except that the returned pointer
shall not be used to access an object.

I have implemented both interfaces on several platforms, both hosted and
freestanding (though malloc is an extension on freestanding platforms).
I have had no difficulty in offering both interfaces on all platforms,
save backward compatibility issues.
In nmalloc, if you request 0 you will actually get
at least ALIGN bytes (which happens to be 8), possibly more if a
residue is too small to be of use in forming another allocation.

So malloc(0) will normally return non-NULL, and as many as 32 bytes
may be available in my system. For that package at least 8 bytes
will be available.

<nod> I see no reason that you could not layer request_malloc, as
proposed, on nmalloc. It simply would check for the 0 case and return 0
before calling nmalloc. Alternatively, if nmalloc were to be rewritten
and layered on request_malloc, it would do as it does now: check for 0
and change it to 1 if found.

I'm clearly not understanding your concern, and I would like to. Sorry
if I'm just being dense.

What would be your preference:

1. request_malloc(0,0) return 0
2. request_malloc(0,0) return nonzero
3. request_malloc(0,0) return 0 or nonzero, implementation defined

?

I'm arguing for 1 or 2, with a slight preference for 1. But I would
really like to avoid 3. I believe it would make portable programs
harder to write, with no real advantage coming from that cost.

I prefer 1 because it requires less heap to implement it. And I am
sensitive to resource constrained (embedded) environments.

-Howard
 
C

CBFalconer

Howard said:
.... snip ...

What would be your preference:

1. request_malloc(0,0) return 0
2. request_malloc(0,0) return nonzero
3. request_malloc(0,0) return 0 or nonzero, implementation defined

You don't have any of those cases. IIRC your prototype is:

void *request_malloc(size_t sz, size_t *actual);

which returns a pointer (NULL for failure), and the actual size
available on success. The logic of the situation insists that
*actual be >= sz on success, else undefined. It can be simulated
(assuming sizeof_malloc() exists) with:

void *request_malloc(size_t sz, size_t *actual)
{
void *p;

if (p = malloc(sz)) *actual = sizeof_malloc(p);
return p;
}

and I consider any other behaviour a contortion.
 
H

Howard Hinnant

CBFalconer said:
You don't have any of those cases. IIRC your prototype is:

void *request_malloc(size_t sz, size_t *actual);

which returns a pointer (NULL for failure), and the actual size
available on success. The logic of the situation insists that
*actual be >= sz on success, else undefined. It can be simulated
(assuming sizeof_malloc() exists) with:

void *request_malloc(size_t sz, size_t *actual)
{
void *p;

if (p = malloc(sz)) *actual = sizeof_malloc(p);
return p;
}

and I consider any other behaviour a contortion.

The proposal shows how request_malloc can be simulated with malloc, and
also states that actual is allowed to be null, in which case *actual
should not be written to.

From your version of the request_malloc simulation, you have chosen 3
(implementation defined behavior for zero sized requests).

Thanks,
-Howard
 
C

CBFalconer

Howard said:
.... snip ...

The proposal shows how request_malloc can be simulated with malloc,
and also states that actual is allowed to be null, in which case
*actual should not be written to.

From your version of the request_malloc simulation, you have chosen
3 (implementation defined behavior for zero sized requests).

Disagree. I have choses "semantically consistent". The null
actual can be handled with:

if ((p = malloc(sz)) && actual) *actual = sizeof_malloc(p);
 
P

Peter Shaggy Haywood

Groovy hepcat (e-mail address removed) was jivin' on 5 Jan 2005 19:29:18
-0800 in comp.lang.c.
malloc size's a cool scene! Dig it!
Inside a program how do i find out what size has been allocated to
pointer using malloc. eg...

**** Read the bloody FAQ and lurk, for crying out loud! ****

It is very rude to post to a newsgroup before lurking for some time
and reading its FAQ. It exists so that you don't have to ask this
question and others like it, since quintillions of people have already
asked, some within the last few weeks or even days, and millions of
others have already answered trillions of times. (Slight exageration.)
Go to http://www.eskimo.com/~scs/C-faq/top.html and read it all.
Then read a couple months of posts in this newsgroup. If your question
is still unanswered, repeat both of these steps until it is answered.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,159
Messages
2,570,883
Members
47,416
Latest member
ReeceDorri

Latest Threads

Top