Allocating memory to nested Structures within a Structure

Discussion in 'C++' started by Amit_Basnak, May 25, 2007.

  1. Amit_Basnak

    Amit_Basnak Guest

    Dear Friends

    I have the follwoing function "tss_fe_get_own_info" which has the
    arguments as shows below
    tss_fe_get_own_info(char *user_id, tss_user_profile_t
    **p_buf_UserSecInfo, error_status_t *retStatus)

    // Structure tss_user_profile_t from the function

    typedef struct {
    tss_user_info_t user_info;
    odss_attribute_value_list_t *ProcAttr;
    odss_attribute_value_list_t *BkOffAttr;
    odss_attribute_value_list_t *WkClusterAttr;
    odss_attribute_value_list_t *CSUAttr;
    } tss_user_profile_t;

    // Structure tss_user_info_t
    typedef struct
    {
    char user_uuid[USER_UUID_LEN+1];
    char user_sec_info_status[USER_ACC_STATUS_LEN+1];
    char user_id[USER_ID_LEN+1];
    char user_name[USER_NAME_LEN+1];
    char employee_id[EMPLOYEE_ID_LEN+1];
    char job_title[JOB_TITLE_LEN+1];
    char job_type[JOB_TYPE_LEN+1];
    char loc_addr[LOC_ADDR_LEN+1];
    char loc_country_code[LOC_CTRY_CODE_LEN+1];
    char loc_city_code[LOC_CITY_CODE_LEN+1];
    char telephone_number[TELE_NUM_LEN+1];
    char expense_code[EXPENSE_CODE_LEN+1];
    char proc_locn_csu[PROC_LOCN_CSU_LEN+1];
    char proc_locn_rpf[RPF_CODE_LEN+1];
    char prim_wk_cluster[PRM_WK_CLUS_LEN+1];
    char experience[EXPERIENCE_LEN+1];
    char oracle_id[ORACLE_ID_LEN+1];
    char oracle_pwd[ORACLE_PWD_LEN+1];
    char user_group[USER_GROUP_LEN+1];
    char date_modified[DATE_STR_LEN+1];
    char date_valid[DATE_STR_LEN+1];
    } tss_user_info_t;

    // odss_attribute_value_list_t
    typedef struct odss_attribute_value_list_t
    {
    [ptr] odss_attribute_value_t *attribute_value;
    [ptr] struct odss_attribute_value_list_t *next;
    } odss_attribute_value_list_t;

    // Structure odss_attribute_value_t

    typedef struct
    {
    unsigned32 length;
    [string, ptr] char *attribute;
    } odss_attribute_value_t;

    If I want to allocate the memory to nested structures in that case
    I have done the follwoing


    tss_user_profile_t **p_buf_UserSecInfo;
    *p_buf_UserSecInfo = new tss_user_profile_t;
    memset((void*) *p_buf_UserSecInfo, '\0',
    sizeof(tss_user_profile_t)); // at this point the profile is
    allocated, as well as the user_info

    unsigned32 len1 = 0;
    char *attr1 = NULL;

    odss_attribute_value_list_t *tmp1 = (*p_buf_UserSecInfo)->ProcAttr; //
    Allocates the ProcAttr pointer :

    ProcAttr = new odss_attribute_value_list_t;
    ProcAttr->attribute_value = new odss_attribute_value_t;
    ProcAttr->attribute_value->length = len1;
    ProcAttr->attribute_value->attribute = attr1;
    ProcAttr->next = tmp1;

    unsigned32 len2 = 0;
    char *attr2 = NULL;

    odss_attribute_value_list_t *tmp2 = (*p_buf_UserSecInfo)-
    >BkOffAttr; // Allocates the BkOffAttr pointer :


    BkOffAttr = new odss_attribute_value_list_t;
    BkOffAttr->attribute_value = new odss_attribute_value_t;
    BkOffAttr->attribute_value->length = len2;
    BkOffAttr->attribute_value->attribute = attr2;
    BkOffAttr->next = tmp2;

    unsigned32 len3 = 0;
    char *attr3 = NULL;

    odss_attribute_value_list_t *tmp3 = (*p_buf_UserSecInfo)-
    >WkClusterAttr; // Allocates the WkClusterAttr pointer :


    WkClusterAttr = new odss_attribute_value_list_t;
    WkClusterAttr->attribute_value = new odss_attribute_value_t;
    WkClusterAttr->attribute_value->length = len3;
    WkClusterAttr->attribute_value->attribute = attr3;
    WkClusterAttr->next = tmp3;

    unsigned32 len4 = 0;
    char *attr4 = NULL;

    odss_attribute_value_list_t *tmp4 = (*p_buf_UserSecInfo)->CSUAttr; //
    Allocates the CSUAttr pointer :

    CSUAttr = new odss_attribute_value_list_t;
    CSUAttr->attribute_value = new odss_attribute_value_t;
    CSUAttr->attribute_value->length = len4;
    CSUAttr->attribute_value->attribute = attr4;
    CSUAttr->next = tmp4;

    Please let me know if this is the correct way to allocate the memory


    thanks
    Amit
    Amit_Basnak, May 25, 2007
    #1
    1. Advertising

  2. Amit_Basnak

    Guest

    Hi,

    > Dear Friends
    >
    > I have the follwoing function "tss_fe_get_own_info" which has the
    > arguments as shows below
    > tss_fe_get_own_info(char *user_id, tss_user_profile_t
    > **p_buf_UserSecInfo, error_status_t *retStatus)
    >
    > // Structure tss_user_profile_t from the function
    >
    >
    > tss_user_profile_t **p_buf_UserSecInfo;
    > *p_buf_UserSecInfo = new tss_user_profile_t;
    > memset((void*) *p_buf_UserSecInfo, '\0',


    Here you got a pointer to a pointer. If the first thing you do after
    declaration is dereferencing the pointer like this:
    *p_buf_UserSecInfo, I think you are running into trouble, because
    p_buf_UserSecInfo is not initialized and is pointing nowhere (or
    anywhere) in memory. Dereferencing it like you do has no sense... Who
    says pointer says array. If you got a pointer of pointer like this
    it's because you want a array of pointers. You'd better do something
    like:

    tss_user_profile_t **p_buf_UserSecInfo;
    p_buf_UserSecInfo = new *tss_user_profile_t[SOME_INTERGER_VALUE]; //
    With SOME_INTERGER_VALUE possibly equal to 1
    for (unsigned int i = 0; i < SOME_INTERGER_VALUE; ++i)
    {
    p_buf_UserSecInfo = new tss_user_profile_t;
    memset((void*) p_buf_UserSecInfo, 0, sizeof(tss_user_profile_t));
    }

    >
    > unsigned32 len1 = 0;
    > char *attr1 = NULL;
    >
    > odss_attribute_value_list_t *tmp1 = (*p_buf_UserSecInfo)->ProcAttr;


    Again, I don't get what you do. (*p_buf_UserSecInfo)->ProcAttr is NULL
    here (remember the memset), so tmp1 is NULL too.

    >
    > ProcAttr = new odss_attribute_value_list_t;


    ProcAttr is not declared anywhere, so it should not compile.

    > ProcAttr->attribute_value = new odss_attribute_value_t;
    > ProcAttr->attribute_value->length = len1;
    > ProcAttr->attribute_value->attribute = attr1;


    attr1 is NULL anyway so you'better write
    ProcAttr->attribute_value->attribute = NULL;

    > ProcAttr->next = tmp1;


    Here too:
    ProcAttr->next = NULL;

    I guess, what do you want to do is:

    (*p_buf_UserSecInfo)->ProcAttr = new odss_attribute_value_list_t;
    (*p_buf_UserSecInfo)->ProcAttr->attribute_value = new
    odss_attribute_value_t;
    (*p_buf_UserSecInfo)->ProcAttr->attribute_value->length = 0;
    (*p_buf_UserSecInfo)->ProcAttr->attribute_value->attribute = NULL;
    (*p_buf_UserSecInfo)->ProcAttr->next = NULL;

    >
    > Please let me know if this is the correct way to allocate the memory
    >


    Or maybe I just didn't understand your post at all :)

    JD
    , May 25, 2007
    #2
    1. Advertising

  3. Amit_Basnak

    Amit_Basnak Guest

    On May 25, 3:59 pm, wrote:
    > Hi,
    >
    > > Dear Friends

    >
    > > I have the follwoing function "tss_fe_get_own_info" which has the
    > > arguments as shows below
    > > tss_fe_get_own_info(char *user_id, tss_user_profile_t
    > > **p_buf_UserSecInfo, error_status_t *retStatus)

    >
    > > // Structure tss_user_profile_t from the function

    >
    > > tss_user_profile_t **p_buf_UserSecInfo;
    > > *p_buf_UserSecInfo = new tss_user_profile_t;
    > > memset((void*) *p_buf_UserSecInfo, '\0',

    >
    > Here you got a pointer to a pointer. If the first thing you do after
    > declaration is dereferencing the pointer like this:
    > *p_buf_UserSecInfo, I think you are running into trouble, because
    > p_buf_UserSecInfo is not initialized and is pointing nowhere (or
    > anywhere) in memory. Dereferencing it like you do has no sense... Who
    > says pointer says array. If you got a pointer of pointer like this
    > it's because you want a array of pointers. You'd better do something
    > like:
    >
    > tss_user_profile_t **p_buf_UserSecInfo;
    > p_buf_UserSecInfo = new *tss_user_profile_t[SOME_INTERGER_VALUE]; //
    > With SOME_INTERGER_VALUE possibly equal to 1
    > for (unsigned int i = 0; i < SOME_INTERGER_VALUE; ++i)
    > {
    > p_buf_UserSecInfo = new tss_user_profile_t;
    > memset((void*) p_buf_UserSecInfo, 0, sizeof(tss_user_profile_t));
    >
    > }
    >
    > > unsigned32 len1 = 0;
    > > char *attr1 = NULL;

    >
    > > odss_attribute_value_list_t *tmp1 = (*p_buf_UserSecInfo)->ProcAttr;

    >
    > Again, I don't get what you do. (*p_buf_UserSecInfo)->ProcAttr is NULL
    > here (remember the memset), so tmp1 is NULL too.
    >
    >
    >
    > > ProcAttr = new odss_attribute_value_list_t;

    >
    > ProcAttr is not declared anywhere, so it should not compile.
    >
    > > ProcAttr->attribute_value = new odss_attribute_value_t;
    > > ProcAttr->attribute_value->length = len1;
    > > ProcAttr->attribute_value->attribute = attr1;

    >
    > attr1 is NULL anyway so you'better write
    > ProcAttr->attribute_value->attribute = NULL;
    >
    > > ProcAttr->next = tmp1;

    >
    > Here too:
    > ProcAttr->next = NULL;
    >
    > I guess, what do you want to do is:
    >
    > (*p_buf_UserSecInfo)->ProcAttr = new odss_attribute_value_list_t;
    > (*p_buf_UserSecInfo)->ProcAttr->attribute_value = new
    > odss_attribute_value_t;
    > (*p_buf_UserSecInfo)->ProcAttr->attribute_value->length = 0;
    > (*p_buf_UserSecInfo)->ProcAttr->attribute_value->attribute = NULL;
    > (*p_buf_UserSecInfo)->ProcAttr->next = NULL;
    >
    >
    >
    > > Please let me know if this is the correct way to allocate the memory

    >
    > Or maybe I just didn't understand your post at all :)
    >
    > JD


    Hi JD thanks for your comments.
    here is the background of what Im doiong This is SOAP Interface that
    Im writing and method tss_fe_get_own_info calls to DCE ( Distributed
    Computing Environment ) and DCE internally calls Oracle DB using
    pro*c. Now in the function
    char *user_id = IN parameter which is passed to SOAP from Front End
    ( J2EE)
    and tss_user_profile_t **p_buf_UserSecInfo , error_status_t
    *retStatus are OUT parameters sent from DCE to Frront End via SOAP.
    I have to stored the return object from DCE to the structure
    tss_user_profile_t
    Since its a linked list type , I have to allocate memory to
    tss_user_profile_t structure dynamically using new operator so that I
    can store the return object. Structure tss_user_profile_t has nested
    structures with pointers , things got complicated.
    This is what I have now and its compiling
    tss_user_profile_t **p_buf_UserSecInfo;
    *p_buf_UserSecInfo = new tss_user_profile_t[1];
    for (unsigned int i = 0; i < 1; ++i)
    {
    p_buf_UserSecInfo = new tss_user_profile_t;
    memset((void*)p_buf_UserSecInfo,0,
    sizeof(tss_user_profile_t));

    }

    (*p_buf_UserSecInfo)->ProcAttr = new odss_attribute_value_list_t;
    (*p_buf_UserSecInfo)->ProcAttr->attribute_value = new
    odss_attribute_value_t;
    (*p_buf_UserSecInfo)->ProcAttr->attribute_value->length = 0;
    (*p_buf_UserSecInfo)->ProcAttr->attribute_value->attribute = NULL;
    (*p_buf_UserSecInfo)->ProcAttr->next = NULL;

    Now If I want to free the allocated memory then do I need to write
    delete for all allocated structures ?
    How it could be done
    Please let me know
    Thanks for your comments
    Amit
    Amit_Basnak, May 25, 2007
    #3
  4. Amit_Basnak

    Guest

    Hi,

    [snip]
    > This is what I have now and its compiling
    > tss_user_profile_t **p_buf_UserSecInfo;
    > *p_buf_UserSecInfo = new tss_user_profile_t[1];
    > for (unsigned int i = 0; i < 1; ++i)
    > {
    > p_buf_UserSecInfo = new tss_user_profile_t;
    > memset((void*)p_buf_UserSecInfo,0,
    > sizeof(tss_user_profile_t));
    >
    > }
    >


    If you are just allocating one element, you don't need a for loop...

    tss_user_profile_t **p_buf_UserSecInfo;
    *p_buf_UserSecInfo = new tss_user_profile_t[1];
    p_buf_UserSecInfo[0] = new tss_user_profile_t;
    memset((void*)p_buf_UserSecInfo[0], 0, sizeof(tss_user_profile_t));


    > (*p_buf_UserSecInfo)->ProcAttr = new odss_attribute_value_list_t;
    > (*p_buf_UserSecInfo)->ProcAttr->attribute_value = new
    > odss_attribute_value_t;
    > (*p_buf_UserSecInfo)->ProcAttr->attribute_value->length = 0;
    > (*p_buf_UserSecInfo)->ProcAttr->attribute_value->attribute = NULL;
    > (*p_buf_UserSecInfo)->ProcAttr->next = NULL;
    >
    > Now If I want to free the allocated memory then do I need to write
    > delete for all allocated structures ?
    > How it could be done


    Well, yes, for every new, you shall have a delete, otherwise you
    would end up with memory leaks. And to delete a linked list a while
    loop seems appropriate...

    odss_attribute_value_list_t *list = (*p_buf_UserSecInfo)->ProcAttr;
    while (list)
    {
    odss_attribute_value_list_t *tmp = list->next;
    delete list->attribute_value;
    delete list;
    list = tmp;
    }

    Here you go.
    I would advise you to have a look to some C tutorial before playing
    around with pointers and dynamic memory allocation:
    http://einstein.drexel.edu/courses/CompPhys/General/C_basics/c_tutorial.html#pointers

    JD
    , May 26, 2007
    #4
    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. Everton da Silva Marques

    Allocating single memory block for multiple structures

    Everton da Silva Marques, Jun 3, 2004, in forum: C Programming
    Replies:
    6
    Views:
    623
    xarax
    Jun 4, 2004
  2. Alfonso Morra
    Replies:
    11
    Views:
    696
    Emmanuel Delahaye
    Sep 24, 2005
  3. Rakesh Kumar
    Replies:
    5
    Views:
    665
    James Kanze
    Dec 21, 2007
  4. Navaneeth
    Replies:
    15
    Views:
    1,490
    Shao Miller
    Aug 7, 2010
  5. Replies:
    1
    Views:
    192
Loading...

Share This Page