Trie data structuring - c

I'm making a trie and I need someone to tell me what's wrong with this code:
typedef struct node
{
struct node *letters[26]={0};
} node;
I want to make it so that in every reference of a node struct, the pointers are all null...
Your help would be greatly appreciated :) Thanks

You can't initialize a type. You can only initialize objects
typedef struct node {
struct node *letters[26];
} node;
node mynode = {0}; /* {{0}} or even {{0, 0, 0, 0, ...}} */

you could go with the simple approach.
You can create an function,which will create and initialize all pointer with NULL then return node object.
Could be as below.
Node* GetMeANode()
{
//Create an object of Node structure here.
//initialize all pointer with `NULL`
// Return it.
}

You cannot initialize members of structs like that, but you can initialize them at instantiation time, or write an initializing function:
#include <string.h>
typedef struct node
{
struct node *letters[26];
} node;
void initNode(node * n) { memset(n->letters, 0, 26 * sizeof(node *)); }
void foo()
{
/* aggregate initialization, efficient */
node n = { 0, 0, 0, /* 26 times */ };
/* helper function */
node m;
initNode(&m);
}
(If this were C++0x, you could initialize struct members in the default constructor's base initializer list, even arrays.)

Related

How to initialize C structs with default values

I have this defined struct:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* prev;
struct Node* next;
} Node;
typedef struct List {
int size = 0;
Node* head = NULL;
Node* tai = NULL;
} List;
List* list1;
For the the node one it is Ok, but for the List one I have a declaration error in visual studio (2022), I am new to C, how to declare default values in C structs?
In C, whether an object is initialized or not depends on how you declare the object, for example whether you declare it as an object of static storage duration (which is initialized to zero unless you explicitly initialize it to something else) or an object of automatic storage duration (which is not initialized, unless you explicitly initialize it).
Therefore, it would not make sense to assign default values to the type definition, because even if the language allowed this, it would not guarantee that the object of that type will be initialized.
However, you can create your own function which initializes your struct to specific values:
void init_list( List *p )
{
p->size = 0;
p->head = NULL;
p->tail = NULL;
}
Assuming that the object is declared inside a function (not at file scope), you can use the following code to declare and initialize the object to default values:
List list1;
init_list( &list1 );
If the object is declared at file scope, you can't call the function init_list at file scope, but you can call the function inside the function main, for example.
Alternatively, when you declare the object, you can also initialize the individual members:
List list1 = { 0, NULL, NULL };
This will also work at file scope.
Since everything is being initialized to zero, it is sufficient to write the following:
List list1 = { 0 };
In that case, all members that are not explicitly assigned a value will be initialized to zero.
In C opposite to C++ you may not initialize data members in structure declarations like you are doing
typedef struct List {
int size = 0;
Node* head = NULL;
Node* tai = NULL;
} List;
Also it does not make sense to declare the global pointer list1.
List* list1;
What you need is to write
typedef struct List {
int size;
Node* head;
Node* tail; // I think you mean `tail` instead of `tai`
} List;
int main( void )
{
List list1 = { .size = 0, .head = NULL, .tail = NULL };
//...;
In C you can't define a struct with default values for the members.
You can however create a global instance with the default values set that you then use for initialization. That's pretty common in the C world.
Example:
typedef struct List {
int size;
Node* head;
Node* tail;
} List;
// The init-value to use
const List List_INIT = {.size = 0, .head = NULL, .tail = NULL};
int main() {
List l = List_INIT; // using the init-value
}
typedef struct List {
int size;
Node* head;
Node* tail;
} List;
What you have defined here is a new data type, you haven't declared any variables of such a type. The name List is not a variable, it is the name of a structure type. The names size, head and tail are not variables, they're the identifiers for the members of this struct.
How to declare default values in C structs?
You can not define a type with default value for the members. Simply provide a definition for it with/after declaration:
List apple;
memset (&apple, 0x00, sizeof apple);
/* Or */
List apple = { .size = 0, .head = NULL, .tail = NULL };
/* Or */
List apple = { .size = 0, .head = 0, .tail = 0 };
/* Or */
List mango = { 0, NULL, NULL };
/* Or */
List banana = { 0, 0, 0};
/* Or */
List orange = { 0 };¹
[1] — §6.7.9 Initialization:
If there are fewer initializers in a brace-enclosed list than there
are elements or members of an aggregate, or fewer characters in a
string literal used to initialize an array of known size than there
are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage
duration

Why do I need double pointers?

I don't understand why I need double pointers inside 'struct graph'. Is it because it allows me to access one of the nodes that I made inside the function makeGraph()?
If I use one pointer (struct node *adjList) then I can't set the nodes to NULL that I made inside makeGraph().
I got the code frome programiz.com and in the article that explains this code it says: Don't let the struct node** adjList overwhelm you. All we are saying is we want to store a pointer to struct node*. This is because we don't know how many vertices the graph will have and so we cannot create an array of Linked Lists at compile time.
If I do: graph->adjList[1] does it go to the address of the second node or goes it inside the node? (I'm talking about the nodes that I create inside makeGraph())
I understand the rest of the code. If anyone can help me it would be appreciated.
#include <stdlib.h>
#include <stdio.h>
struct node
{
int vertex;
struct node *next;
};
struct graph
{
int numVertices;
struct node **adjList; // <--- THIS ONE
};
struct graph *makeGraph(int vertices) // Creating a Graph
{
struct graph *graph = malloc(sizeof(struct graph));
graph->numVertices = vertices;
graph->adjList = malloc(sizeof(struct node) * vertices); // creating the nodes
for (int i = 0; i < vertices; i++)
graph->adjList[i] = NULL; // Setting all nodes to NULL
return graph;
}
void addEdge(struct graph *graph, int src, int dest) // Add Edge
{
struct node *newNode = makeNode(dest);
newNode->next = graph->adjList[src];
graph->adjList[src] = newNode;
struct node *newNode2 = makeNode(src);
newNode2->next = graph->adjList[dest];
graph->adjList[dest] = newNode2;
return;
int main()
{
struct graph *graph1 = makeGraph(4);
addEdge(graph1, 0, 1);
addEdge(graph1, 0, 2);
addEdge(graph1, 0, 3);
}
An adjacency list is being represented as a linked list of struct node. The list is accessed by a pointer to the first element of the list. (The pointer will be NULL when the list is empty.) The pointer has type struct node *.
The graph has a number of vertices as set in the numVertices member of struct graph. Each vertex needs an adjacency list, and each adjacency list needs a struct node *. So the graph needs an array of struct node * of length numVertices. The authors of the code chose to allocate the array dynamically as a separate memory block pointed to by the adjList member. The type of the adjList member is a pointer to the element type. The element type is struct node * so the type of the adjList member is struct node **.
There is another way to allocate the memory for the struct graph and its adjacency list. They could be allocated as single block by changing the adjList member to be a flexible array member, as shown below:
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
struct node
{
int vertex;
struct node *next;
};
struct graph
{
int numVertices;
struct node *adjList[]; // <--- FLEXIBLE ARRAY MEMBER
};
struct graph *makeGraph(int vertices) // Creating a Graph
{
struct graph *graph = malloc(offsetof(struct graph, adjList[vertices]));
graph->numVertices = vertices;
for (int i = 0; i < vertices; i++)
graph->adjList[i] = NULL; // Setting all nodes to NULL
return graph;
}
offsetof(struct graph, adjList[vertices]) is the offset in bytes from the address of a struct graph to the address of the adjList[vertices] array member element. Allocating a block of memory of that size is just large enough to hold a struct graph plus the array of pointers. Another way to specify the size is sizeof(struct graph) + vertices * sizeof(struct node *) or alternatively sizeof(struct graph) + vertices * sizeof(graph->adjList[0]), but I think using the offsetof macro is a more succinct way to specify the size.

meaning of a struct within a struct in c [duplicate]

This question already has answers here:
What is self-referencing structure in C?
(3 answers)
Closed 3 years ago.
Can someone explain what we mean when we do, like what does struct Node* next do. does it create a pointer of type struct? any help and resources about structures in c would be helpful
struct Node {
int dest;
struct Node* next;
};
"struct" itself is not a type. "struct [tag]" is a type, for example "struct Node" in your code.
In your case you define a structure type. Every structure of that type will contain a pointer to another structure of that type as a member called "next".
This allows you to chain the structures together in a so called linked list. You store a pointer to the first structure in a variable, then you can follow the chain of links down to the structure you need.
For example, you can do
struct Node *start;
start = malloc(sizeof struct Node);
start->dest = 7;
start->next = malloc(sizeof struct Node);
start->next->dest = 13;
start->next->next = malloc(sizeof struct Node);
start->next->next->dest = 19;
printf("%d %d %d\n", start->dest, start->next->dest, start->next->next->dest);
free(start->next->next);
free(start->next);
free(start);
Please note that this code omits all error handling, in real code you have to handle the case when malloc returns NULL.
Also, in real code you would use such a structure in loops that traverse the chain, not directly as above.
As #Serge is pointing out in comments, is not a struct within a struct, is a reference (a pointer) to an object of the same type, an example:
#include <stdio.h>
struct Node {
int dest;
struct Node* next;
};
int main(void)
{
/* An array of nodes */
struct Node nodes[] = {
{1, &nodes[1]}, // next points to the next element
{2, &nodes[2]}, // next points to the next element
{3, NULL} // next points to null
};
/* A pointer to the first element of the array */
struct Node *node = nodes;
while (node) {
printf("%d\n", node->dest);
node = node->next; // node moves to the next element
}
return 0;
}
Output:
1
2
3
Of course, in my example there is no benefit in using a linked list, linked lists are useful when we don't know the number of elements before-hand.
Another example using dynamic memory:
struct Node *head, *node;
node = head = calloc(1, sizeof *node);
node->dest = 1;
while (more_elements_needed) {
node->next = calloc(1, sizeof *node);
node->next->dest = node->dest + 1;
node = node->next;
}
for (node = head; node != NULL; node = node->next) {
printf("%d\n", node->dest);
}

Dynamic data structure for Union Struct in C

Given this struct
struct node {
struct node* next;
union {
int lockId;
pthread_t threadId;
} id;
};
What is the correct way to initialize a dynamic array using malloc/realloc to store pointers to this struct?
I have tried:
struct node* nodes = (struct node*)malloc(n * sizeof(struct node*));
but I when compiling I get an error saying: initializer element is not constant
even though I am using #define MAXNODES 10
As for now, I am currently using a static array (fixed-size) by doing:
node *(nodes[MAXNODES]);
Any help would be greatly appreciated!
There is no problem with your data struct here, using an Union or not doesn't matter.
Your problem comes from the fact that the syntax for creating arrays is not correct.
In the following you can see how to create both dynamic and static arrays:
#include <stdlib.h>
#include <pthread.h>
#define MAX_NODES 10
struct node {
struct node *next;
union {
int lockId;
pthread_t threadId;
} id;
};
int main()
{
struct node nodes_static[MAX_NODES];
int n = MAX_NODES;
struct node* nodes_dynamic = (struct node*)malloc(sizeof(struct node) * n);
}
Please also note, that it is good practice to verify the return value of a dynamic allocation and that the dynamic memory should be freed after use.

Is it possible to store a struct into a linked list?

I'm writing a program that solves a maze using DFS algorithm and stack. I was thinking of storing the coordinates of the path used to get to the end onto a struct containing integers x,y for coordinates and then pushing that struct onto a stack to perform other instructions on (print, pop, etc.).
I have searched all over and have yet to find anything that helps. So I went ahead and set it up but I'm getting an error about type compatibility since I have my node data as an int but I'm trying to put in a struct. Being new to linked lists I have only seen data as an int or char. Finally, is it even possible to do what I want? If not could you suggest a way of passing both x,y coordinates onto the stack? Thank you in advance.
Here's a sample of my code, where to save space a1 is an instance of COORD, and list is initialized as well as the maze and such.
typedef struct node {
int data; /* Value or data stored in node*/
struct node *pNext; /* Reference to the next node address */
} NODE;
/*Structure declares pointers for front and back of the list*/
typedef struct LIST {
NODE *front;
NODE *back;
} LIST;
/* Structure to pass multiple values onto stack */
typedef struct COORD{
int x;
int y;
}COORD;
/*Example of one of the functions */
void lst_push_front(LIST *l, COORD *a1) {
NODE *p = malloc(sizeof(NODE));
p->data = a1;
p->pNext = l->front;
l->front = p;
if(l->back == NULL) // was empty, now one elem
l->back = p;
}
Check the code below.
Since COORD is a structure you can include it in another structure as shown in the below code.
Also make sure that the ordering of the structures are proper.
p->data.x is the right way to access the members of the structure COORD
#include <stdio.h>
/* Structure to pass multiple values onto stack */
typedef struct COORD{
int x;
int y;
}COORD;
typedef struct node {
COORD data; /* --> Changes done here */
struct node *pNext; /* Reference to the next node address */
} NODE;
/*Structure declares pointers for front and back of the list*/
typedef struct LIST {
NODE *front;
NODE *back;
} LIST;
void func(COORD *q)
{
NODE *p = malloc(sizeof(NODE));
p->data.x = q->x;
p->data.y = q->y;
printf("%d %d",p->data.x,p->data.y);
free(p);
}
int main(void) {
COORD *q = malloc(sizeof(COORD));
q->x = 20;
q->y = 30;
func(q);
free(q);
return 0;
}
As #barak manos mentions you should put COORD struct before NODE and change int data to COORD data and use p->data = *a1

Resources