Does C guarantee the data layout of the memory allocated by malloc function?

Discussion in 'C Programming' started by lovecreatesbeauty, Sep 23, 2005.

  1. Hello experts,


    1. Does C guarantee the data layout of the memory allocated by malloc
    function on the heap. I mean, for example, if I allocate a array of 100
    elements of structure, can I always reference a correct/valid structure
    member upon that allocated memory?

    If I allocate memory, for example like this way:

    lp_Person = (person_t *)malloc(CNT * sizeof(person_t));

    I guess the malloc/compiler doesn't know the detail of the data type
    person_t. It only know the size of the object of the data type. So, how
    can I use the members of the object of person_t (suppose it had
    members) without compiler knowing it.

    2. Is the base type of a pointer very important? I ever read one book,
    it says "A pointer is not just a pointer, but a pointer with some
    particular data type" (perhaps like this). Is it right?

    3. If I allocate memory inside a function named f1(), is it better for
    me to delay the de-allocation of that memory in some other functions
    later?


    Could you please also give me some more suggestion on my following
    code, thank you very much.


    lovecreatesbeauty


    #include <stdlib.h>
    #include <stddef.h>
    #include <string.h>


    #define NMLEN 30

    typedef enum {
    male = 1,
    female = 2
    } gender_t;

    typedef struct {
    char name[NMLEN];
    gender_t gender;
    int age;
    } person_t;

    typedef enum {
    false = 0,
    true = 1
    } bool_t;


    int NameListInitialization(void){
    const int CNT = 100;
    int ln_LoopCnt = 0;
    person_t * lp_Person = NULL;
    char la_PersonName[NMLEN] = {'\0'};
    bool_t lb_IsAllocated = false;


    lp_Person = (person_t *)malloc(CNT * sizeof(person_t));
    if (lp_Person != NULL){
    lb_IsAllocated = true;

    for (ln_LoopCnt = 0; ln_LoopCnt < CNT ; ++ln_LoopCnt){
    memset(la_PersonName, 0x00, sizeof(la_PersonName));
    memset(lp_Person[ln_LoopCnt].name,
    0x00,
    sizeof(lp_Person[ln_LoopCnt].name));

    itoa(ln_LoopCnt, la_PersonName, 10);
    strcat(la_PersonName, "-Anonymous");
    strcpy(lp_Person[ln_LoopCnt].name, la_PersonName);
    lp_Person[ln_LoopCnt].gender = (gender_t)(
    ln_LoopCnt % 2 + 1);
    lp_Person[ln_LoopCnt].age = ln_LoopCnt;
    }
    }

    /* do something here ... */

    if (lb_IsAllocated == true){
    free(lp_Person); /* Can I call this free in other place? */
    }

    return 0;
    }
    lovecreatesbeauty, Sep 23, 2005
    #1
    1. Advertising

  2. >1. Does C guarantee the data layout of the memory allocated by malloc
    >function on the heap. I mean, for example, if I allocate a array of 100
    >elements of structure, can I always reference a correct/valid structure
    >member upon that allocated memory?


    What does reference ... upon mean? Is that some kind of kinky byte sex?

    The memory allocated by malloc() is guaranteed to be contiguous
    within itself, otherwise there would be no way to find it with just
    the pointer returned by malloc(). The memory allocated in one call
    to malloc() is not guaranteed to be contiguous with the memory in
    any other call to malloc() (and in one implementation I'm familiar
    with, no two chunks of memory allocated by malloc() will EVER be
    contiguous to each other).

    >If I allocate memory, for example like this way:
    >
    >lp_Person = (person_t *)malloc(CNT * sizeof(person_t));


    Don't cast the return value of malloc().

    >I guess the malloc/compiler doesn't know the detail of the data type
    >person_t. It only know the size of the object of the data type. So, how
    >can I use the members of the object of person_t (suppose it had
    >members) without compiler knowing it.


    Assuming a lp_Person is declared as a person_t *, the first
    element is lp_Person[0], and the next one is lp_Person[1], ...
    Then you can refer to things like lp_Person[0].hat_size .

    >2. Is the base type of a pointer very important? I ever read one book,
    >it says "A pointer is not just a pointer, but a pointer with some
    >particular data type" (perhaps like this). Is it right?


    Yes. The difference in address between lp_Person[0] and lp_Person[1]
    is the size of a person_t. The difference between ((char *)
    lp_Person)[0] and ((char *) lp_Person)[1] is one byte.

    >3. If I allocate memory inside a function named f1(), is it better for
    >me to delay the de-allocation of that memory in some other functions
    >later?


    Don't free the memory before you finish needing it.
    Free the memory after you do finish needing it.

    >Could you please also give me some more suggestion on my following
    >code, thank you very much.
    >
    >
    >lovecreatesbeauty
    >
    >
    >#include <stdlib.h>
    >#include <stddef.h>
    >#include <string.h>
    >
    >
    >#define NMLEN 30
    >
    >typedef enum {
    > male = 1,
    > female = 2
    >} gender_t;
    >
    >typedef struct {
    > char name[NMLEN];


    30 characters isn't nearly enough for real human names.

    > gender_t gender;
    > int age;
    >} person_t;
    >
    >typedef enum {
    > false = 0,
    > true = 1
    >} bool_t;
    >
    >
    >int NameListInitialization(void){
    > const int CNT = 100;
    > int ln_LoopCnt = 0;
    > person_t * lp_Person = NULL;
    > char la_PersonName[NMLEN] = {'\0'};
    > bool_t lb_IsAllocated = false;
    >
    >
    > lp_Person = (person_t *)malloc(CNT * sizeof(person_t));
    > if (lp_Person != NULL){
    > lb_IsAllocated = true;
    >
    > for (ln_LoopCnt = 0; ln_LoopCnt < CNT ; ++ln_LoopCnt){
    > memset(la_PersonName, 0x00, sizeof(la_PersonName));
    > memset(lp_Person[ln_LoopCnt].name,
    > 0x00,
    > sizeof(lp_Person[ln_LoopCnt].name));
    >
    > itoa(ln_LoopCnt, la_PersonName, 10);

    There is no function itoa() in standard C.

    > strcat(la_PersonName, "-Anonymous");
    > strcpy(lp_Person[ln_LoopCnt].name, la_PersonName);
    > lp_Person[ln_LoopCnt].gender = (gender_t)(
    > ln_LoopCnt % 2 + 1);
    > lp_Person[ln_LoopCnt].age = ln_LoopCnt;
    > }
    > }
    >
    > /* do something here ... */
    >
    > if (lb_IsAllocated == true){
    > free(lp_Person); /* Can I call this free in other place? */

    As written, lp_Person is about to be lost, so you CAN'T use its value
    in another place. If, on the other hand, you returned lp_Person to
    the function, it would be possible to free it in another place.

    > }
    >
    > return 0;
    >}


    Gordon L. Burditt
    Gordon Burditt, Sep 23, 2005
    #2
    1. Advertising

  3. lovecreatesbeauty

    KJ Guest

    Friend when u allocate memory using malloc the bytes allocaed is
    always contiguous. It returns the starting byte offset. Now questions
    comes how do we manipulate the data stored in bytes. For example
    int *p = (int*)malloc(10*sizeof(int));

    p will get the starting byte offset. where will p+1 refer to. Here
    comes the type of pointer. Since the pointer p is of int type (assuming
    sizeof(int) is 4) p+1 or p[1]refers to starting offset + 4bytes. so now
    it points to the second int value of the allocation.

    if u uset structure then increasing pointer of structure by one means
    pointing to next structure values.

    U can free the allocation anywhere but u must have the pointer pointing
    to the starting offset of the allocation.
    KJ, Sep 23, 2005
    #3
  4. Re: Does C guarantee the data layout of the memory allocated by mallocfunction?

    lovecreatesbeauty wrote:
    > Hello experts,
    >
    >
    > 1. Does C guarantee the data layout of the memory allocated by malloc
    > function on the heap. I mean, for example, if I allocate a array of 100
    > elements of structure, can I always reference a correct/valid structure
    > member upon that allocated memory?
    >
    > If I allocate memory, for example like this way:
    >
    > lp_Person = (person_t *)malloc(CNT * sizeof(person_t));

    Don't cast the return value of malloc !

    > I guess the malloc/compiler doesn't know the detail of the data type
    > person_t. It only know the size of the object of the data type. So, how
    > can I use the members of the object of person_t (suppose it had
    > members) without compiler knowing it.

    malloc doesn't know, but it's required to give you memory aligned suitable
    for any data type.

    You can't access the members of a structure without the compiler knowing
    about them.

    > 2. Is the base type of a pointer very important? I ever read one book,
    > it says "A pointer is not just a pointer, but a pointer with some
    > particular data type" (perhaps like this). Is it right?

    Yes.

    > 3. If I allocate memory inside a function named f1(), is it better for
    > me to delay the de-allocation of that memory in some other functions
    > later?

    Deallocate when done with it, wherever that is.
    =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=, Sep 23, 2005
    #4
  5. Gordon Burditt wrote:
    > What does reference ... upon mean? Is that some kind of kinky byte sex?


    Hi Gordon, thanks for your kindly help. Sorry for my poor English. I
    mean that Whether I refer to the members of the object of the
    particular data type in the allocated member?

    When allocate with malloc(), it only knows the size but don't know the
    layout of the object of that particular data type. I'm a little
    confused on it.

    > Don't cast the return value of malloc().


    Does it comply to the latest Language Standard?

    > Gordon L. Burditt


    Best Regards

    lovecreatesbeauty
    lovecreatesbeauty, Sep 23, 2005
    #5
  6. lovecreatesbeauty

    Jason Curl Guest

    Re: Does C guarantee the data layout of the memory allocated by mallocfunction?

    lovecreatesbeauty wrote:
    > Gordon Burditt wrote:
    >
    >>What does reference ... upon mean? Is that some kind of kinky byte sex?

    >
    >
    > Hi Gordon, thanks for your kindly help. Sorry for my poor English. I
    > mean that Whether I refer to the members of the object of the
    > particular data type in the allocated member?
    >
    > When allocate with malloc(), it only knows the size but don't know the
    > layout of the object of that particular data type. I'm a little
    > confused on it.


    Sure, as Gordon mentions, your only guarantee then is that the memory
    block for the size you requested is contiguous if malloc() was successful.

    malloc() doesn't need to know about the layout of your memory. You
    define that by the datatype pointer you assigned with malloc(). e.g.

    struct mystruct {
    int element1;
    char element2;
    } *pmystruct;

    pmystruct = malloc(sizeof(mystruct));

    So, the type 'struct mystruct' defines the layout. You just need to make
    sure that you allocate enough memory, and this is what the 'sizeof'
    operator is used for.

    >
    >
    >>Don't cast the return value of malloc().

    >
    >
    > Does it comply to the latest Language Standard?
    >
    >
    >> Gordon L. Burditt

    >
    >
    > Best Regards
    >
    > lovecreatesbeauty
    >
    Jason Curl, Sep 23, 2005
    #6
  7. lovecreatesbeauty

    SM Ryan Guest

    "lovecreatesbeauty" <> wrote:
    # Hello experts,
    #
    #
    # 1. Does C guarantee the data layout of the memory allocated by malloc
    # function on the heap. I mean, for example, if I allocate a array of 100
    # elements of structure, can I always reference a correct/valid structure
    # member upon that allocated memory?
    #
    # If I allocate memory, for example like this way:
    #
    # lp_Person = (person_t *)malloc(CNT * sizeof(person_t));

    If you allocate N*sizeof(T) chars, you will have enough space for
    at least N elements. If you save the pointer,
    T *p=malloc(N*sizeof(T)), you can access successive elements as
    p[0], p[1], p[2], ... , p[N-1]. Any alignment issues and filler space
    are taken care for you.

    # 2. Is the base type of a pointer very important? I ever read one book,
    # it says "A pointer is not just a pointer, but a pointer with some
    # particular data type" (perhaps like this). Is it right?

    You can cast a function pointer to a function pointer and a data
    pointer to a data pointer. All struct pointers are the same; for
    other data pointers, the compiler is allowed to use different
    representations.

    malloc returns a (void*). If you assign or cast to (T*), the
    compiler will insert any magic if it needs to change the pointer
    value.

    On some systems, a function pointer can be a code address and
    a data address. That's why data and function pointers are different
    beasts.

    # 3. If I allocate memory inside a function named f1(), is it better for
    # me to delay the de-allocation of that memory in some other functions
    # later?

    There is no 'better' or 'worse'. It is a matter of interface design.

    --
    SM Ryan http://www.rawbw.com/~wyrmwif/
    No pleasure, no rapture, no exquisite sin greater than central air.
    SM Ryan, Sep 23, 2005
    #7
    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. Replies:
    5
    Views:
    617
    Matt Wharton
    Dec 9, 2004
  2. Jonas
    Replies:
    21
    Views:
    1,108
    Mark McIntyre
    Oct 14, 2003
  3. Peter
    Replies:
    34
    Views:
    1,942
    Richard Tobin
    Oct 22, 2004
  4. Pallav singh
    Replies:
    1
    Views:
    350
    Triple-DES
    Mar 27, 2008
  5. Gene
    Replies:
    0
    Views:
    448
Loading...

Share This Page