Allocating memory to nested Structures within a Structure

A

Amit_Basnak

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
 
J

jean.daniel.michaud

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
 
A

Amit_Basnak

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
 
J

jean.daniel.michaud

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
 

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

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top