Dynamic allocation of union of structs - c

I am trying to create a union of 2 structs (dfp and affine) and want to allocate them dynamically. I am getting errors in creating particular struct array inside union. Am I declaring union in right way?
#include <stdio.h>
#include <stdlib.h>
struct{
int fp;
}dfp;
struct{
int scale;
int zp;
}affine;
union{
struct dfp *df;
struct affine *af;
}quant;
struct member{
int total;
union quant arr;
};
int main(void) {
// your code goes here
struct member* ptr;
ptr = (struct member *)malloc(sizeof(struct member));
ptr->total = 2;
int type = 0;
if(!type){
ptr->arr->df = (struct dfp*)malloc(ptr->total*sizeof(struct dfp)); //error
for(int i=0;i<2;i++){
ptr->arr->df->fp[i] = 10;
}
}
else{
ptr->arr->af = (struct affine*)malloc(ptr->total*sizeof(struct affine)); //error
for(int i=0;i<2;i++){
ptr->arr->af->scale[i] = 10;
ptr->arr->af->zp[i] = 20;
}
}
return 0;
}

Most issues have already been pointed out by others separately. This is my attempt at writing a complete answer with explanations and advice.
First off, please check your exact compiler warnings and errors. These are your best help in resolving these kind of issues.
The program does not contain a union of structs, but a union of pointers to structs.
The program's definitions are not correct. Taking dfp as an example. This, struct { int fp; } dfp;, defines an anonymous struct with the the variable name dfp. The name of the struct should go before the struct declaration list, e.g. struct dfp { int fp; };. See here or see the C standard specifications.
Judging by the code in main, the member variables of the structs should be arrays of size 2 instead of single ints.
The operator -> is for "member access using a pointer". Since arr is not a pointer, use a dot (.) to access its members. See here.
Dynamically allocated memory must be free'd, or else the program will have one or more memory leaks.
Here is the full code with all mentioned corrections:
#include <stdio.h>
#include <stdlib.h>
struct dfp {
int fp[2];
};
struct affine {
int scale[2];
int zp[2];
};
union quant {
struct dfp *df;
struct affine *af;
};
struct member {
int total;
union quant arr;
};
int main(void) {
struct member* ptr;
ptr = (struct member *)malloc(sizeof(struct member));
ptr->total = 2;
int type = 0;
if(!type) {
ptr->arr.df = (struct dfp*)malloc(ptr->total*sizeof(struct dfp));
for(int i=0;i<2;i++){
ptr->arr.df->fp[i] = 10;
}
}
else {
ptr->arr.af = (struct affine*)malloc(ptr->total*sizeof(struct affine));
for(int i=0;i<2;i++){
ptr->arr.af->scale[i] = 10;
ptr->arr.af->zp[i] = 20;
}
}
if(!type) {
free(ptr->arr.df);
}
else {
free(ptr->arr.af);
}
free(ptr);
}

Correct the struct definition as below:
struct dfp {
int fp;
};
struct affine{
int scale;
int zp;
};

Related

Can a pointer point to a struct of item of list of order

typedef struct item
{
char itemName[32];
float price;
int quantity;
}ITEM;
typedef struct list
{
void* item[5];
int (*compare)(void*, void*);
int length;
}LIST;
typedef struct order
{
int orderId;
float orderTotal;
LIST* orderItems;
int length;
} ORDER;
int compareItemPrice(void* p1, void* p2){
ITEM* p = (ITEM*)p1;
ITEM* q = (ITEM*)p2;
if(p->price>q->price)
{
return 1;
} else if(p->price<q->price)
{
return -1;
} else {
return 0;
}
}
Code above is my structures and function wrote in C. When I implement code below, it showed me errors. The errors was all about ITEM* p which was incomplete definition of struct list.
ITEM* getExpensiveItem(ORDER* o){ // Maximum item price
ITEM* p = o->orderItems->item;
ITEM* expensiveItem = p;
for(int i=1; i<o->orderItems->length-1; i++)
{
if(compareItemPrice(p, (p+i)) < 0)
{
expensiveItem = p+i;
}
}
return expensiveItem;
}
Code like
struct a
{
int i;
} A;
will give a variable A that you can use like
A.i = 42;
However, it seems that you really are trying to create a new type. So try:
typedef struct a // Notice the "typedef" in start of line
{
int i;
} A;
That will give a a type A that can be used like:
A var;
A* pVar;
var.i = 42;
pVar = &var;
....
Also notice that your struct order uses the type LIST. So LIST must be declared before struct order. Further, the type CUSTOMER must also be declared which it currently isn't.
So your code should probably be like:
#define N 42 // Made this up as it isn't in your code
typedef struct customer // Made this up as it isn't in your code
{
int x;
} CUSTOMER;
typedef struct list
{
void* item[N];
int (*compare)(void*, void*);
int length;
}LIST;
typedef struct order
{
int orderId;
float orderTotal;
LIST* orderItems;
CUSTOMER* customer;
int length;
} ORDER;
typedef struct item
{
char itemName[32];
float price;
int quantity;
}ITEM;
Also notice that this line has a problem:
ITEM* p = o->orderItems->item;
The type of o->orderItems->item is array of void pointer due to void* item[N]; in struct list. In other words: You are trying to assign an array of pointer to a single pointer. I'm not really sure what you want to do but maybe like:
ITEM* p = o->orderItems->item[0];

How to use struct within an union, within a struct in C?

i am currently having a lot of struggle with a, for me personally, very complex structure
struct crypto_tfm
{
uint32_t crt_flags;
union
{
struct ablkcipher_tfm ablkcipher;
struct aead_tfm aead;
struct blkcipher_tfm blkcipher;
struct cipher_tfm cipher;
struct hash_tfm hash;
struct compress_tfm compress;
struct rng_tfm rng;
} crt_u;
void (*exit)(struct crypto_tfm *tfm);
struct crypto_alg *crt_alg;
void *crt_ctx[] CRYPTO_MINALIGN_ATTR;
};
I completely have no idea how to use this struct. so basicly i am completely lost with this
the function using this expects a struct crypto_tfm *tfm
first idea is the following:
struct crypto_tfm *new_tfm()
{
struct crypto_tfm *tfm = malloc(sizeof(struct crypto_tfm));
tfm -> crt_flags = 0;
tfm -> crt_u.
}
but i dont know how to get further,
the given structs within the union are also using another structs. kinda too complicated for me right now
This is untested, but should be a good example:
struct st_a
{
int a;
};
struct st_b
{
int b;
};
union un_c
{
struct st_a aa;
struct st_b bb;
};
struct st_d
{
int d;
union un_c cc;
};
int main ()
{
struct st_d *dd = malloc (sizeof (struct st_d));
dd->d = 0;
/* The following two lines might (probably are) accessing
the same area of memory. */
dd->cc.aa.a = 0;
dd->cc.bb.b = 1;
}

Assignment makes pointer from Integer without a Cast in Structure

I'm making a program that dynamically creates a list of integers.
int ins_dlist(int data, struct dlist **p){
struct dlist *q;
if((*p)->sz == (*p)->maxsz){
q = realloc(*p, DLISTSZ((*p)->maxsz + INCRSZ));
if(q == NULL)
return (-1);
q->maxsz += INCRSZ;
*p = q;
}
//(*p)->item[(*p)->sz++] = data; <-Gives me pointer from integer without cast
*((*p)->item + (*p)->sz++) = data;
return(0);
}
My problem is on *((*p)->item + (*p)->sz++) = data; I tried declaring it in different ways but I still can't get access to the sz variable in my struct.
Heres my struct declaration, its inside a file named dlist.h:
#include <stdlib.h>
struct dlist{
int sz;
int maxsz;
int *item[1];
};
#define INITSZ 5
#define INCRSZ 5
#define DLISTSZ(n) ((size_t)(sizeof(struct dlist)) + ((n-1)*sizeof(int)))
struct dlist *init_dlist(int num);
int ins_dlist(int data, struct dlist **p);
You probably wanted to define dllist as:
struct dlist{
int sz;
int maxsz;
int item[1];
};

error: invalid type argument of '->' (have 'struct node')

Why cant i access the pointer "Cells" like an array ? i have allocated the appropriate memory why wont it act like an array here? it works like an array for a pointer of basic data types.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAX 10
struct node
{
int e;
struct node *next;
};
typedef struct node *List;
typedef struct node *Position;
struct Hashtable
{
int Tablesize;
List Cells;
};
typedef struct Hashtable *HashT;
HashT Initialize(int SIZE,HashT H)
{
int i;
H=(HashT)malloc(sizeof(struct Hashtable));
if(H!=NULL)
{
H->Tablesize=SIZE;
printf("\n\t%d",H->Tablesize);
H->Cells=(List)malloc(sizeof(struct node)* H->Tablesize);
should it not act like an array from here on?
if(H->Cells!=NULL)
{
for(i=0;i<H->Tablesize;i++)
the following lines are the ones that throw the error
{ H->Cells[i]->next=NULL;
H->Cells[i]->e=i;
printf("\n %d",H->Cells[i]->e);
}
}
}
else printf("\nError!Out of Space");
}
int main()
{
HashT H;
H=Initialize(10,H);
return 0;
}
The error I get is as in the title-error: invalid type argument of '->' (have 'struct node').
A correct version of your code is given below. It is always advisable not to use pointers while using typedef.
The only problem with your code apart from that was your access method.
H->cells[i]->next will throw an error.
Also H->cells->[i]e was invalid syntax.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAX 10
struct node
{
int e;
struct node *next;
};
typedef struct node List;
typedef struct node Position;
struct Hashtable
{
int Tablesize;
List *Cells;
};
typedef struct Hashtable HashT;
HashT Initialize(int SIZE,HashT *H)
{
int i;
H=(HashT*)malloc(sizeof(struct Hashtable));
if(H!=NULL)
{
H->Tablesize=SIZE;
printf("\n\t%d",H->Tablesize);
H->Cells=(List*)malloc(sizeof(List)*H->Tablesize);
//should it not act like an array from here on?
if(H->Cells!=NULL)
{
for(i=0;i<H->Tablesize;i++)
//the following lines are the ones that throw the error
{
H->Cells[i].next=NULL;
H->Cells[i].e=i;
printf("\n %d",H->Cells[i].e);
}
}
}
else printf("\nError!Out of Space");
return *H;
}
int main()
{
HashT H;
H=Initialize(10,&H); //return is not required as already we are passing by address
return 0;
}
The
H->Cells[i]->next
should be
H->Cells[i].next
(Similarly for e.)
This is a version of your program without the typedefs. Which one is more readable?
#include <stdio.h>
#include <stdlib.h>
struct node {
struct node *next;
int e;
};
struct Hashtable {
unsigned Tablesize;
struct node *Cells;
};
struct Hashtable *Initialize(unsigned size)
{
unsigned iii;
struct Hashtable *hp;
hp = malloc (sizeof *hp);
if(!hp) {
fprintf(stderr, "Error!Out of Space\n");
return NULL;
}
hp->Cells = malloc(size * sizeof *hp->Cells );
if(!hp->Cells) {
hp->Tablesize = 0;
return hp;
}
hp->Tablesize = size;
fprintf(stderr, "\t%u\n", hp->Tablesize);
for(iii=0; iii < hp->Tablesize; iii++) {
hp->Cells[iii].next = NULL;
hp->Cells[iii].e = iii;
fprintf( stderr, " %u\n", hp->Cells[iii].e);
}
return hp;
}
int main()
{
struct Hashtable *hashtab;
hashtab = Initialize(10);
return 0;
}
The changes:
removed the typedefs; since they are confusing
removed the casts from malloc() not needed and potentially dangerous.
changed the sizes to unsigned. A size can never be negative
diagnostic output should go to stderr.
a few of levels of indentation can be avoided by doing the error-case first, and returning early from the function on error.

how to access the struct?

struct result {
int number;
int length;
};
struct result findLongestSeq(int intarray[], int size) {
result->number // undefined symbol
}
how to access the struct result inside the function findLongestSeq?
thanks
struct result {
int number;
int length;
};
struct result findLongestSeq(int intarray[], int size) {
struct result result;
result.number = 0;
result.length = 42;
return result;
}
If you are dealing with struct result foo then you access its members via foo.number.
If however you are dealing with a pointer to foo (struct result *foo) then you access its members via foo->number.
If you were to manually allocate your result struct via
struct result *result = (struct result *)malloc(sizeof (struct result));
Then you'd have to access its members via result->number (and would be responsible for freeing it once not used anymore).
Further more I'd rather use this for the sake of better readability:
typedef struct {
int number;
int length;
} ResultStruct;
This way you can then use ResultStruct result; instead of redundant and verbose struct result result;.
You have to keep in mind that by simply typing
struct result {
int number;
int length;
};
you only define how a struct with name result actually looks like, i.e. of what parts it is made up. This is a general definition, but you have variable of that type yet.
To access values of this struct you have to create a variable by
struct result myResult;
or however you want to call it. At this point you are able to access the members of this struct with myResult.number

Resources