I have these structures:
struct generic_attribute{
int current_value;
int previous_value;
};
union union_attribute{
struct complex_attribute *complex;
struct generic_attribute *generic;
};
struct tagged_attribute{
enum{GENERIC_ATTRIBUTE, COMPLEX_ATTRIBUTE} code;
union union_attribute *attribute;
};
I keep getting segmentation fault errors because I am not allocating memory properly when creating an object of type tagged_attribute
.
struct tagged_attribute* construct_tagged_attribute(int num_args, int *args){
struct tagged_attribute *ta_ptr;
ta_ptr = malloc (sizeof(struct tagged_attribute));
ta_ptr->code = GENERIC_ATTRIBUTE;
//the problem is here:
ta_ptr->attribute->generic = malloc (sizeof(struct generic_attribute));
ta_ptr->attribute->generic = construct_generic_attribute(args[0]);
return ta_ptr;
}
construct_generic_attribute
returns a pointer to a generic_attribute
object. I want ta_ptr->attribute->generic
to contain a pointer to a generic_attribute
object. This pointer to a generic_attribute
object is output by the construct_generic_attribute
function.
What would be the proper way to do this?
You need to allocate space for the attribute
member too.
struct tagged_attribute* construct_tagged_attribute(int num_args, int *args)
{
struct tagged_attribute *ta_ptr;
ta_ptr = malloc(sizeof(struct tagged_attribute));
if (ta_ptr == NULL)
return NULL;
ta_ptr->code = GENERIC_ATTRIBUTE;
ta_ptr->attribute = malloc(sizeof(*ta_ptr->attribute));
if (ta_ptr->attribute == NULL)
{
free(ta_ptr);
return NULL;
}
/* ? ta_ptr->attribute->generic = ? construct_generic_attribute(args[0]); ? */
/* not sure this is what you want */
return ta_ptr;
}
and you should not malloc()
for the attribute and then reassign the pointer, in fact your union should not have poitner, because then it doesn't serve any purpose at all, it's a union
where both members are pointers.
This would make more sense
union union_attribute {
struct complex_attribute complex;
struct generic_attribute generic;
};
so you would set the union value like
ta_ptr->attribute.generic = construct_generic_attribute(args[0]);