malloc() question...

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

  1. Chad

    Chad Guest

    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?
     
    Chad, Nov 16, 2010
    #1
    1. Advertising

  2. Chad

    Ian Collins Guest

    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
    #2
    1. Advertising

  3. Chad

    Chad Guest

    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.
     
    Chad, Nov 16, 2010
    #3
  4. Chad

    Ian Collins Guest

    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
    #4
  5. Chad

    Seebs Guest

    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.

    -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
    #5
  6. Chad

    arnuld Guest

    > 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
    #6
  7. Chad

    James Waldby Guest

    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
    #7
  8. Chad

    Seebs Guest

    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
    something very fundamental about C:

    *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
    #8
  9. 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
    #9
  10. 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
    #10
  11. 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
    #11
  12. 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
    #12
  13. Chad

    Seebs Guest

    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
    #13
  14. 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
    addressable storage unit is unspecified.

    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
    #14
  15. Chad

    Seebs Guest

    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
    #15
  16. Chad

    Lew Pitcher Guest

    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
    #16
  17. 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
    #17
  18. Chad

    Seebs Guest

    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
    #18
  19. 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
    thinking about using for a tftp header.
    char paddding="0"; for two padding bytes.
    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
    2 bytes string pad string pad

    Would malloc() be a more streamlined answer?

    Bill
     
    Bill Cunningham, Nov 19, 2010
    #19
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John
    Replies:
    13
    Views:
    734
  2. ravi
    Replies:
    0
    Views:
    481
  3. Peter
    Replies:
    34
    Views:
    2,055
    Richard Tobin
    Oct 22, 2004
  4. porting non-malloc code to malloc

    , Feb 18, 2005, in forum: C Programming
    Replies:
    3
    Views:
    503
    Walter Roberson
    Feb 19, 2005
  5. Johs32

    to malloc or not to malloc??

    Johs32, Mar 30, 2006, in forum: C Programming
    Replies:
    4
    Views:
    343
    Captain Winston
    Mar 30, 2006
Loading...

Share This Page