C-Void pointer inside a generic list (Contains stucture) - c

I have 2 different stuctures but i need to contain them in the same generic list.
The structures are :
typedef struct Val1{
int num1;
int num2;
int num3;
}Val1;
typedef struct Val2{
char name[50];
char surname[50];
int ID;
}Val2;
And the list is:
typedef stuct list {
void *value;
struct node *next;
}list;
typedef struct L_head{
node *head;
int num_members;
}L_head;
I need to use the same list implementation but the list needs to handle both of the
strucrure types.I cant figure out how to initialize the list and put some elements in the list .Any advice will be helpfull.

The canonical solution for C would add a common initial field having distinct values to both structures.
typedef struct Val1 {
int discriminator;
int num1;
int num2;
int num3;
} Val1;
typedef struct Val2 {
int discriminator;
char name[50];
char surname[50];
int ID;
} Val2;
If neccessary, you can define a new struct instead.
That has the advantage of preserving the previous layout and alignment guarantees:
struct packed {
int discriminator;
union {struct Val1;struct Val2};
};
Anyway, you could integrate it directly into the node:
typedef stuct node {
struct node *next;
int discriminator; /* You might want to reserve 0 for no content */
union {struct Val1;struct Val2};
} node;
The technical term of the solution is "discriminated union".

You can have a two element array of void pointers - One pointing to struct of type 1 and another to type 2. This should help to get the right structures with the right casting.

If you are able to distinguish between the type of each of the nodes, you could resort to C unions, like in:
typedef struct Val1{
int num1;
int num2;
int num3;
} Val1;
typedef struct Val2{
char name[50];
char surname[50];
int ID;
} Val2;
union {
Val1 val1;
Val2 val2;
} Val;

For adding the list items, you need to cast them to (void*).
In order to determine the type again upon access, you could add another field(enum) to the list, which stores it's type.
I bet this is some training or homework. If C++ is possible:
start using std::list or boost::list implementation.

Related

Difference between these 2 declarations of structures in C

I'm working on this project for college and they gave me a sample code to use while declaring a structure, the other one is how I declared it with the information on PowerPoints and other study material.
This is the code they gave me:
typedef struct sala local, *plocal;
struct sala {
int id;
int capacidade;
int liga[3];
};
This is the code for another structure i did:
typedef struct pessoa {
char id[15];
int idade;
char estado;
int dias;
} pessoa;
Can anyone explain the difference to me ?
In my code editor "local" and "*local" appear in blue. (I use Netbeans).
This typedef declaration
typedef struct sala local, *local;
struct sala {
int id;
int capacidade;
int liga[3];
};
is invalid because the name local is declared twice with different meanings: the first one as an alias for the type struct sala and the second one as an alias for the type struct sala *.
This is the difference between the first and the second typedef declarations.:)
As for the placement of typedef declaration then it may be placed either before a corresponding structure definition. together with structure definition or after structure definition.
For example
typedef struct A A;
struct A
{
int x;
};
or
typedef struct A
{
int x;
} A;
or
struct A
{
int x;
};
typedef struct A A;
An essence difference between these declarations is that if you want to refer to the defined structure inside its definition then in the second and third cases you have to use the type name struct A because the typedef name A was not yet declared.
For example
typedef struct Node Node;
struct Node
{
int x;
Node *next;
};
but for example
typedef struct Node
{
int x;
struct Node *next;
} Node;

Initializing a struct within a union within a struct in C

struct huffnode{
int freq;
union{
struct children
{
struct huffnode * l;
struct huffnode * r;
}
char c;
}un;
};
I'm trying to create a program that implements a huffman tree but in order to do that I need to create nodes with a left and right node pointer in them. The problem is that I don't know how to initialize the struct children. Anyone have any ideas?

error: dereferencing pointer to incomplete type

Looked through many other SO posts related to this, but none were able to help me. So, I have the following structs defined:
typedef struct
{
int created;
double data;
int timeLeft;
int destination;
}dataPacket;
typedef struct
{
dataPacket *array;
int currIndex;
int firstIndex;
int nextTick;
int maxLength;
int length;
int stime;
int total;
}packetBuffer;
typedef struct{
int mac;
struct wire *lconnection;
struct wire *rconnection;
int numRecieved;
struct packetBuffer *buffer;
int i;
int backoff;
}node;
typedef struct{
float length;
float speed;
int busy;
struct dataPacket *currPacket;
struct node *lnode;
struct node *rnode;
}wire;
And then I'm trying to use the following function:
int sendPacket(node *n, int tick)
{
if(n->buffer->length > 0)
{
if(n->backoff <= 0)
{
if (n->lconnection->busy != 0 || n->lconnection->busy != 0)
{
n->i++;
n->backoff = (512/W * genrand()*(pow(2,n->i)-1))/TICK_LENGTH;
}
else
{
n->lconnection->busy = 1;
n->rconnection->busy = 1;
n->lconnection->currPacket = n->buffer[n->buffer->currIndex];
n->rconnection->currPacket = n->buffer[n->buffer->currIndex];
}
}
else
{
n->backoff--;
}
}
}
I'm getting the error described in the title everytime I try to access a member of buffer, lconnection, or rconnection.
struct packetBuffer *buffer;
You've defined a type packetBuffer (a typedef for an otherwise anonymous struct).
You haven't defined struct packetBuffer.
In the absence of an existing type struct packetBuffer, the compiler treats it as an incomplete type, assuming that you'll complete it later. The declaration
struct packetBuffer *buffer;
is perfectly legal, but you can't dereference buffer unless the type struct packetBuffer is visible.
Just drop the struct keyword.
(My personal preference is to drop the typedef and consistently refer to struct types as struct whatever, but that's a matter of style and taste.)
The following:
typedef struct {
int x;
char *y;
...
} my_struct;
creates an identifier for an anonymous structure. In order, for a structure to refer to an instance of itself, it must not be "anonymous":
typedef struct my_struct {
int x;
char *y;
struct my_struct *link
....
} my_struct_t;
This means that my_struct_t is now the type struct my_struct and not just an anonymous struct. Also, note that struct my_struct can be used within its own structure definition. That is not possible with anonymous structs.
As a final complication, the my_struct in struct my_struct is in a differenct "namespace" than the my_struct_t. This is sometimes used to to simplify (or confuse) things in code like this:
typedef struct my_struct {
int x;
char *y;
struct my_struct *link
....
} my_struct;
Now I can use my_struct anywhere in my code instead of struct my_struct.
Finally, you could separate the typedef from the structure definition to achieve the same effect:
struct my_struct {
int x;
char *y;
struct my_struct *link;
....
};
typedef struct my_struct my_struct;
As noted in David R.Hanson's C Interfaces and Implementations, "This definition is legal because structure, union, and enumeration tags occupy a same name space that is separate from the space for variables, functions, and type names."

Linked List Help, Singly Linked (Multiple Structures) (C Programming)

I need some help with Linked Lists.
I have figured out how to do individual linked list, but I am struggling when trying to implement multiple struct's and lists.
My last program was all used with Structs but now I must implement linked list's.
It says to use "External Pointers" in the functions to use in traversing through the various lists.
This is homework for one of my classes, I am not asking for you all to do it for me, but I am asking to help point me in the right direction.
The structs are as follows:
struct stockItem
{
char stockName[60];
char stockType[60];
int itemNumber;
float actualCost;
float markUp;
int totalCurrentInventory;
int monthlyRestock;
float price; //stores actual cost + markup
};
struct roomData
{
float widthFeet, widthInch;
float lengthFeet, lengthInch;
char roomName[100];
int roomNumberOfType;
char roomType[6]; //char of room type
int roomStock[100][2]; //for storing each room stock types
int roomHasStock; //if the room has a stock avaliable
int roomStockCount; //how many stocks the room has
float area; // sq ft
float rentalRate;
float profitsPerRoom;
float netProfit;
float grossProfit;
char stockLine[200];
};
struct staffData
{
char firstName[100];
char lastName[100];
char fullName[100];
int employeeNumber;
char typeOfEmployee[10];
char payType[10];
float hourlyWage;
float salary;
int hours;
char address[150];
char city[150];
char state[10];
int zip;
char phone[30];
float yearlyTotalPay;
struct hireDate //holds staff hire date
{
int month;
int day;
int year;
}hireDate;
struct birthDate //holds staff birth date
{
int month;
int day;
int year;
}birthDate;
};
typedef struct YourStructNode_ {
struct YourStructNode_ * next;
struct YourStructNode_ * prev;
YourStruct data;
} T_YourStructList;
Replace "YourStruct" by the name of your structs to make a doubly linked list.
Even if you make more than once T_XXXX_List with this pattern you should manipulate the list with the same function since the two first fields of T_Node is always the same.
Write add, insert, remove functions to manipulate this structure.
Is your linked list supposed to utilize the structs that you have developed? This way you have a linked list where each node contains an instance of all of those structs you listed.
struct node {
struct node *left;
struct node *right;
roomData room;
stockItem stock;
staffData staff;
hireDate hire;
birthDate birth;
};

C union and struct question

I have a tree structure. The nodes would have a leaf node type and internal node type, so I defined these structures, so the internal node would be able to point to either internal nodes or leaf nodes. However, I am having trouble in accessing the child pointers, how can I do that, after all does my code make sense at all?
typedef struct leaf_node_t {
int type;
int key;
int *data_ptr[2]; //This will point to real data.
} leaf_node_t;
typedef struct internal_node_t {
int type;
int key;
typedef union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
} node_ptr;
} internal_node_t;
The typedef of node_ptr does not actually add a field to its enclosing struct. The following adds the fields first, and then follows up with the typedef. The other change I made was having the union represent a single pointer, leaving it to the struct that uses it to decide how many pointers it wants.
typedef struct internal_node_t{
int type;
int key;
union node_ptr_t {
struct internal_node_t* iptr;
leaf_node_t* lptr;
} node_ptr[2];
}internal_node_t;
typedef union node_ptr_t node_ptr_t;
Try this:
typedef struct leaf_node_t{
int key;
int *data_ptr[2];//this will point to real data
} leaf_node_t;
struct internal_node_t;
typedef union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
} node_ptr;
typedef struct internal_node_t{
int key;
node_ptr node;
} internal_node_t;
int main()
{
internal_node_t inode;
leaf_node_t* leaf_node = inode.node.lptrs[0];
return 0;
}
Alternately, if you don't actually need to use the union typedef anywhere else:
typedef struct leaf_node_t{
int key;
int *data_ptr[2];//this will point to real data
}leaf_node_t;
typedef struct internal_node_t{
int key;
union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
}node_ptr;
}internal_node_t;
int main()
{
internal_node_t inode;
leaf_node_t* leaf_node = inode.node_ptr.lptrs[0];
return 0;
}
You should add a flag in the internal_node to know what is the node_ptr, if it's an internal_node_t or a leaf_node_t. Probably a int isInternal[2]; (after the key and before the typedef). if it's 0 the it's internal, if it's 1 then it's leaf_node_t. C language doesn't have a typeof or a GetType to know what type of memory is pointed by a pointer (and C++ has it only if you are compiling with the RTTI "option" activated)

Resources