# malloc() question...

Discussion in 'C Programming' started by Chad, Nov 16, 2010.

Let's say I call malloc() like the following

char *a = malloc(20);

and then do

free(a);

Does 20 chars or 20 ints get freed?

2. ### Ian CollinsGuest

On 11/17/10 09:12 AM, Chad wrote:
> Let's say I call malloc() like the following
>
> char *a = malloc(20);
>
> and then do
>
> free(a);
>
> Does 20 chars or 20 ints get freed?

Why would 20 ints get freed when you have requested 20 chars? I guess
the answer would be "both" if sizeof(int) were 1!

--
Ian Collins

Ian Collins, Nov 16, 2010

On Nov 16, 12:22 pm, Ian Collins <> wrote:
> On 11/17/10 09:12 AM, Chad wrote:
>
> > Let's say I call malloc() like the following

>
> > char *a = malloc(20);

>
> > and then do

>
> > free(a);

>
> > Does 20 chars or 20 ints get freed?

>
> Why would 20 ints get freed when you have requested 20 chars?  I guess
> the answer would be "both" if sizeof(int) were 1!
>

I thought 20 was ot type int.

4. ### Ian CollinsGuest

On 11/17/10 09:24 AM, Chad wrote:
> On Nov 16, 12:22 pm, Ian Collins<> wrote:
>> On 11/17/10 09:12 AM, Chad wrote:
>>
>>> Let's say I call malloc() like the following

>>
>>> char *a = malloc(20);

>>
>>> and then do

>>
>>> free(a);

>>
>>> Does 20 chars or 20 ints get freed?

>>
>> Why would 20 ints get freed when you have requested 20 chars? I guess
>> the answer would be "both" if sizeof(int) were 1!
>>

>
> I thought 20 was ot type int.

It is, but the parameter for malloc is size_t and the unit of the value
requested is bytes.

--
Ian Collins

Ian Collins, Nov 16, 2010
5. ### SeebsGuest

> Let's say I call malloc() like the following

> char *a = malloc(20);

> and then do

> free(a);

> Does 20 chars or 20 ints get freed?

No.

The space that was allocated gets freed. It doesn't matter what you think
the pointer is; if it's the address malloc() returned, the whole space is
freed regardless.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach /
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Seebs, Nov 16, 2010
6. ### arnuldGuest

> On Tue, 16 Nov 2010 20:52:39 +0000, Seebs wrote:

>> On 2010-11-16, Chad <> wrote:
>> Let's say I call malloc() like the following

>> char *a = malloc(20);
>> and then do

>
>> free(a);

>
>> Does 20 chars or 20 ints get freed?

> No.
>
> The space that was allocated gets freed. It doesn't matter what you
> think the pointer is; if it's the address malloc() returned, the whole
> space is freed regardless.

We have not passed anything to the free() except pointer and it still free
()s the allocated memory. It means free() knows that char* a has 20x8
bits (assuming char is 8 bit here) without even telling it ?

--
www.lispmachine.wordpress.com

arnuld, Nov 17, 2010
7. ### James WaldbyGuest

On Wed, 17 Nov 2010 04:42:23 +0000, arnuld wrote:
>> On Tue, 16 Nov 2010 20:52:39 +0000, Seebs wrote:
>>> On 2010-11-16, Chad <> wrote: Let's say I call
>>> malloc() like the following

>
>>> char *a = malloc(20);
>>> and then do

>>
>>> free(a);

>>
>>> Does 20 chars or 20 ints get freed?

>
>> No.
>>
>> The space that was allocated gets freed. It doesn't matter what you
>> think the pointer is; if it's the address malloc() returned, the whole
>> space is freed regardless.

>
> We have not passed anything to the free() except pointer and it still
> free ()s the allocated memory. It means free() knows that char* a has
> 20x8 bits (assuming char is 8 bit here) without even telling it ?

See <http://c-faq.com/malloc/freesize.html> for an answer to that
question, or see <http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=malloc>
for more general info about malloc. If you want to find out how much
overhead an allocated block uses on your system, try a program like
the following (adjust the constants 21 and 28 if necessary).

/* Re: overhead bytes for allocated memory */
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int k;
char *now=NULL, *next;
for (k=21; k<28; ++k) {
next = malloc(k+1);
if (!next) exit(1);
if (now)
printf ("k=%2d next-now = %3ld now=%p\n",
k, next-now, now);
now=next;
}
return 0;
}

On my AMD x64 system this displayed the following, which
indicates that overhead is not less than 8 bytes (ie, 32-24).
k=22 next-now = 32 now=0x601010
k=23 next-now = 32 now=0x601030
k=24 next-now = 32 now=0x601050
k=25 next-now = 48 now=0x601070
k=26 next-now = 48 now=0x6010a0
k=27 next-now = 48 now=0x6010d0

--
jiw

James Waldby, Nov 17, 2010
8. ### SeebsGuest

On 2010-11-17, arnuld <> wrote:
>> On Tue, 16 Nov 2010 20:52:39 +0000, Seebs wrote:
>> The space that was allocated gets freed. It doesn't matter what you
>> think the pointer is; if it's the address malloc() returned, the whole
>> space is freed regardless.

> We have not passed anything to the free() except pointer and it still free
> ()s the allocated memory.

Yes.

> It means free() knows that char* a has 20x8
> bits (assuming char is 8 bit here) without even telling it ?

Stop thinking in terms of bits! BIT SIZE IS TOTALLY IRRELEVANT TO THIS
QUESTION. That you even mention bits says you are not understanding

*STORAGE IN C HAPPENS IN TERMS OF char NOT IN TERMS OF BITS*.

Bitfields are a semi-exception, but they are really packed into objects
of some integer type, and the integer type is still some number of chars
of storage.

Yes, free() knows how much space was allocated at that address. Part
of what malloc()/free() do is keep an internal table that allows free()
to free the space allocated. That's why you can only pass free()
pointers returned by malloc() (or null pointers).

When you request 20 bytes, malloc() records in some way how what block
of space it gave you (which may well have more than 20 bytes in it), so
that when you free the memory, that hunk of space can be made available
for further allocation.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach /
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Seebs, Nov 17, 2010
9. ### Keith ThompsonGuest

Seebs <> writes:
[...]
> *STORAGE IN C HAPPENS IN TERMS OF char NOT IN TERMS OF BITS*.
>
> Bitfields are a semi-exception, but they are really packed into objects
> of some integer type, and the integer type is still some number of chars
> of storage.

You mean struct, not integer, yes?

> Yes, free() knows how much space was allocated at that address. Part
> of what malloc()/free() do is keep an internal table that allows free()
> to free the space allocated. That's why you can only pass free()
> pointers returned by malloc() (or null pointers).

It's conceivable that the memory allocation system doesn't even know
how much space was allocated, as long as it can arrange for free()
to do the right thing. A hypothetical example: You call malloc(10),
and it actually allocates 16 bytes, without remembering that you
asked for only 10. Or maybe it remembers both the 10 and the 16,
so it only has to copy 10 bytes if you call realloc(). Later, the 16
bytes following your allocation are free()d, and the system combines
them with the original 16 bytes to create a 32-byte allocated block
(perhaps because it guesses that you might want to call realloc() to
expand it further). Not necessarily plausible, but entirely legal.

> When you request 20 bytes, malloc() records in some way how what block
> of space it gave you (which may well have more than 20 bytes in it), so
> that when you free the memory, that hunk of space can be made available
> for further allocation.

Right. Note that the "table" you mentioned earlier needn't be any
particular data structure; information about allocated memory could be
scattered through the "heap".

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Nov 17, 2010
10. ### Michael FoukarakisGuest

On Nov 16, 10:12 pm, Chad <> wrote:
> Let's say I call malloc() like the following
>
> char *a = malloc(20);
>
> and then do
>
> free(a);
>
> Does 20 chars or 20 ints get freed?

It's impossible to say. It depends on the implementation, specifically
how much space is actually allocated by malloc() when you request 20
bytes (20 bytes + bookkeeping + header + footer etc).

Michael Foukarakis, Nov 17, 2010
11. ### William HughesGuest

On Nov 17, 3:38 am, Keith Thompson <> wrote:
> Seebs <> writes:
>
> [...]
>
> > *STORAGE IN C HAPPENS IN TERMS OF char NOT IN TERMS OF BITS*.

>
> > Bitfields are a semi-exception, but they are really packed into objects
> > of some integer type, and the integer type is still some number of chars
> > of storage.

>
> You mean struct, not integer, yes?
>
> > Yes, free() knows how much space was allocated at that address.  Part
> > of what malloc()/free() do is keep an internal table that allows free()
> > to free the space allocated.  That's why you can only pass free()
> > pointers returned by malloc() (or null pointers).

>
> It's conceivable that the memory allocation system doesn't even know
> how much space was allocated, as long as it can arrange for free()
> to do the right thing.  A hypothetical example: You call malloc(10),
> and it actually allocates 16 bytes, without remembering that you
> asked for only 10.  Or maybe it remembers both the 10 and the 16,
> so it only has to copy 10 bytes if you call realloc().  Later, the 16
> bytes following your allocation are free()d, and the system combines
> them with the original 16 bytes to create a 32-byte allocated block
> (perhaps because it guesses that you might want to call realloc() to
> expand it further).  Not necessarily plausible, but entirely legal.

If you want plausible consider a system that preallocates a bunch
of small buffers for efficieny reasons. The size and number
of these buffers are set when the system is compiled.
Malloc has to know the size, but free does not. Free only
has to know if a points to one of these buffers. So it is quite
plausible that free(a) has no idea how much memory a points
to.

-William Hughes

William Hughes, Nov 17, 2010
12. ### Keith ThompsonGuest

Michael Foukarakis <> writes:
> On Nov 16, 10:12Â pm, Chad <> wrote:
>> Let's say I call malloc() like the following
>>
>> char *a = malloc(20);
>>
>> and then do
>>
>> free(a);
>>
>> Does 20 chars or 20 ints get freed?

>
> It's impossible to say. It depends on the implementation, specifically
> how much space is actually allocated by malloc() when you request 20
> bytes (20 bytes + bookkeeping + header + footer etc).

Yes, but if it happens to free 20 ints (i.e., 20 * sizeof(int)
bytes), then that's purely coincidental.

In a followup, Chad said he thought it might free 20 ints because
20 is of type int. That's completely irrelevant. The argument
to malloc is converted to size_t (because that's the type of
malloc's parameter), and its value specifies the number of bytes
to be allocated.

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Nov 17, 2010
13. ### SeebsGuest

On 2010-11-17, Keith Thompson <> wrote:
> Seebs <> writes:
> [...]
>> *STORAGE IN C HAPPENS IN TERMS OF char NOT IN TERMS OF BITS*.

>> Bitfields are a semi-exception, but they are really packed into objects
>> of some integer type, and the integer type is still some number of chars
>> of storage.

> You mean struct, not integer, yes?

I'm pretty sure I mean integer (which has to be in a struct) -- maybe I'm
confused, but I thought I remembered that bitfield objects were combined
into integers which were secretly part of the structure in some way.

> It's conceivable that the memory allocation system doesn't even know
> how much space was allocated, as long as it can arrange for free()
> to do the right thing. A hypothetical example: You call malloc(10),
> and it actually allocates 16 bytes, without remembering that you
> asked for only 10. Or maybe it remembers both the 10 and the 16,
> so it only has to copy 10 bytes if you call realloc(). Later, the 16
> bytes following your allocation are free()d, and the system combines
> them with the original 16 bytes to create a 32-byte allocated block
> (perhaps because it guesses that you might want to call realloc() to
> expand it further). Not necessarily plausible, but entirely legal.

True. In practice, it nearly always has some idea of the size of the
block, because it handles more than one size of block. Though a naive
implementation built on mmap() could bypass that.

> Right. Note that the "table" you mentioned earlier needn't be any
> particular data structure; information about allocated memory could be
> scattered through the "heap".

Yup!

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach /
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Seebs, Nov 17, 2010
14. ### Keith ThompsonGuest

Seebs <> writes:
> On 2010-11-17, Keith Thompson <> wrote:
>> Seebs <> writes:
>> [...]
>>> *STORAGE IN C HAPPENS IN TERMS OF char NOT IN TERMS OF BITS*.

>
>>> Bitfields are a semi-exception, but they are really packed into objects
>>> of some integer type, and the integer type is still some number of chars
>>> of storage.

>
>> You mean struct, not integer, yes?

>
> I'm pretty sure I mean integer (which has to be in a struct) -- maybe I'm
> confused, but I thought I remembered that bitfield objects were combined
> into integers which were secretly part of the structure in some way.

Um, I don't think so, or at least I don't think the standard expresses
it in those terms.

6.7.2.1p10:

An implementation may allocate any addressable storage unit
large enough to hold a bitfield. If enough space remains,
a bit-field that immediately follows another bit-field in
a structure shall be packed into adjacent bits of the same
unit. If insufficient space remains, whether a bit-field that
does not fit is put into the next unit or overlaps adjacent
units is implementation-defined. The order of allocation of
bit-fields within a unit (high-order to low-order or low-order
to high-order) is implementation-defined. The alignment of the

It's not implied that these "addressable storage units" are integers.

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Nov 17, 2010
15. ### SeebsGuest

On 2010-11-17, Keith Thompson <> wrote:
> An implementation may allocate any addressable storage unit
> large enough to hold a bitfield. If enough space remains,
> a bit-field that immediately follows another bit-field in
> a structure shall be packed into adjacent bits of the same
> unit. If insufficient space remains, whether a bit-field that
> does not fit is put into the next unit or overlaps adjacent
> units is implementation-defined. The order of allocation of
> bit-fields within a unit (high-order to low-order or low-order
> to high-order) is implementation-defined. The alignment of the
> addressable storage unit is unspecified.

> It's not implied that these "addressable storage units" are integers.

Huh! Right you are. I guess this is cognitive overflow from the fact
that bitfields are declared with integer types. So I tend to think of
them as being shoved into integers.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach /
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Seebs, Nov 17, 2010
16. ### Lew PitcherGuest

On November 17, 2010 16:59, in comp.lang.c, wrote:

> On 2010-11-17, Keith Thompson <> wrote:
>> An implementation may allocate any addressable storage unit
>> large enough to hold a bitfield. If enough space remains,
>> a bit-field that immediately follows another bit-field in
>> a structure shall be packed into adjacent bits of the same
>> unit. If insufficient space remains, whether a bit-field that
>> does not fit is put into the next unit or overlaps adjacent
>> units is implementation-defined. The order of allocation of
>> bit-fields within a unit (high-order to low-order or low-order
>> to high-order) is implementation-defined. The alignment of the
>> addressable storage unit is unspecified.

>
>> It's not implied that these "addressable storage units" are integers.

>
> Huh! Right you are. I guess this is cognitive overflow from the fact
> that bitfields are declared with integer types. So I tend to think of
> them as being shoved into integers.

FWIW, K&R C imposed (had?) an integer bias:

"A field may not overlap an int boundary; if the width would cause this to
happen, the field is aligned at the next int boundary.
...
Other restrictions to bear in mind: fields are unsigned; they may be
stored only in int's (or, equivalently, unsigned's); they are not arrays;
they do not have addresses, so the & operator cannot be applied to them."

The C Programming Language ((C) 1978, Bell Laboratories),
Section 6.7 - "Fields"

Perhaps that's what you remembered?
--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.ca/
---------- Slackware - Because I know what I'm doing. ------

Lew Pitcher, Nov 17, 2010
17. ### Keith ThompsonGuest

Seebs <> writes:
> On 2010-11-17, Keith Thompson <> wrote:
>> An implementation may allocate any addressable storage unit
>> large enough to hold a bitfield. If enough space remains,
>> a bit-field that immediately follows another bit-field in
>> a structure shall be packed into adjacent bits of the same
>> unit. If insufficient space remains, whether a bit-field that
>> does not fit is put into the next unit or overlaps adjacent
>> units is implementation-defined. The order of allocation of
>> bit-fields within a unit (high-order to low-order or low-order
>> to high-order) is implementation-defined. The alignment of the
>> addressable storage unit is unspecified.

>
>> It's not implied that these "addressable storage units" are integers.

>
> Huh! Right you are. I guess this is cognitive overflow from the fact
> that bitfields are declared with integer types. So I tend to think of
> them as being shoved into integers.

They're not shoved into integers; integers are shoved into them.

("In Soviet Russia ...")

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Nov 17, 2010
18. ### SeebsGuest

On 2010-11-17, Keith Thompson <> wrote:
> They're not shoved into integers; integers are shoved into them.

Lew found the old K&R quote that probably got the integer stuff shoved
into my brain.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach /
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Seebs, Nov 17, 2010
19. ### Bill CunninghamGuest

Re: malloc() question...[byte question]

Michael Foukarakis wrote:
> On Nov 16, 10:12 pm, Chad <> wrote:
>> Let's say I call malloc() like the following
>>
>> char *a = malloc(20);
>>
>> and then do
>>
>> free(a);
>>
>> Does 20 chars or 20 ints get freed?

>
> It's impossible to say. It depends on the implementation, specifically
> how much space is actually allocated by malloc() when you request 20
> bytes (20 bytes + bookkeeping + header + footer etc).

Humm. Interesting thread. Answers some of my questions. I have this I am
short opcode=/*1-5*/ depending on the situation.
char *filename=/*whatever*/
char *mode=/*string mode*/

I've considered sticking all this about in a struct. The RRQ and WRQ header
is such

opcode|filename|1 byte|mode|1 byte