Arithmetic of the double pointers with a data structure - c

i tryied to write the hashtable and found this github repository: enter link description here. I'm having difficulty understanding this code:
struct entry_s
{
char* key;
char* value;
struct entry_s* next;
};
typedef struct entry_s entry_t;
struct hashtable_s
{
int size;
struct entry_s** table;
};
typedef struct hashtable_s hashtable_t;
I've two questions:
Why there using the typedef struct entry_s entry_t; instead of
struct entry_s
{
char* key;
char* value;
struct entry_s* next;
}entry_t;
because if i use second way i will have error.
What does that code mean: struct entry_s** table;
I know this question can be so eazy to answer, but I will be glad if you help me

Why there using typedef struct entry_s entry_t; instead of
struct entry_s
{
char* key;
char* value;
struct entry_s* next;
};entry_t;
The syntax you give is not correct and does not do what you think. The last line, };entry_t;, is regarded as a new statement, because your compiler expects that after each ; there will be a new one. What you want to write is the following code:
struct entry_s
{
char* key;
char* value;
struct entry_s* next;
} entry_t;
This structure is a linked list, you can see that one of the fields (the last one) uses the same structure to keep a data. In a more abstract way, you can see this code such as:
struct my_linked_list_s
{
T data;
struct my_linked_list_s *next;
};
In C, a recursive data type (i.e. one that is used in its own definition), requires a pointer (for reasons of measuring the size of the structure*), which is why we see one in the next field. Then, in order to distinguish between the "internal" use of the structure and its external use, we define an alias type:
typedef struct my_linked_list_s my_linked_list_t;
Or, in your case:
typedef struct entry_s entry_t;
This is not a necessary thing though, but your implementation has chosen to do so. You can see the naming convention: _s for "structure" and _t for "type".
Because if i use second way i will have error.
You should read your compiler's error messages more carefully, it would have helped you understand what's wrong.
What does that code mean: struct entry_s** table;
This is an array of pointers. Your implementation has chosen to use linked lists and pointers, this function clearly describes the adding part.
For a better overview of the C hash tables, check out this answer.
*To determine the size of a structure (sizeof(struct my_struct)), the sum of the size of all fields is used. If we were to determine the size of a recursive structure without using a pointer (a pointer has a fixed size, for any type of data), then the structure would have an infinite size. To avoid this problem, we therefore use a pointer.

The answer for the second question is you are decalring an array of pointer that can store the pointers of the type struct entry_s** .

Related

how to fix "invalid use of undefined type" of struct type in C?

Sorry first for my bad English. I'm begginer in C, trying to make a Singly Linked List.
This is my setup of the List:
#include <stdio.h>
#include <stdlib.h>
typedef int Element;
struct
{
Element Data;
struct Node *Next;
} Node;
typedef struct Node *Position;
typedef Position List;
This is how I initialize this Struct (i dont know if this function is wrong):
void resetList(List *L)
{
*L = (struct Node *)malloc(sizeof(Node));
};
My problem is, wherever I used the (->), I will got this error
error: invalid use of undefined type ...
the compiler mark the error at any (->) in my code. For example:
int isEmpty(List L)
{
return (L->Next == 0);
};
will get the error at (->).
I know my code is so dump. Please help me. Thanks.
My problem is, wherever I used the (->), I will got this error
Your struct needs to be defined as a type and at the same time a self-referencing type, able to point at a variable which is of the same type as itself. In can be done like this:
typedef struct Node
{
Element Data;
struct Node *Next;
} Node;
Where the first Node is a struct tag, which is a name allowed to co-exist with the type name Node later defined at the } Node;.
Hiding pointers behind a typdef like typedef struct Node *Position; is horrible practice, because it achieves nothing except making the code much harder to read for everyone including yourself. There's no need for a typedef at all here, just declare a variable Node* Position.
Similarly, drop the typedef Position List;, creating new types just for the heck of it only creates clutter.
This is how I initialize this Struct (i dont know if this function is wrong):
The reason why you aren't sure, is because of all the obscure typedefs. Consider rewriting the function as:
void resetList (Node** list)
{
*list = malloc(sizeof(Node));
};
The reason why it has to be a pointer-to-pointer is explained here: Dynamic memory access only works inside function
As for what this function does, resetList is a very weird name for a function allocating a single node. I would expect it to delete the previous list if present and then maybe allocate a new node.
In general, the first declaration of struct Node is not correct. If you specify the name of the structure at the end of its declaration, you are not specifying data type, but you create only the struct variable. Therefore, the compiler doesn't know how to allocate struct Node *Next; item in your struct.
You can simply repair your code by moving the name of the structure:
typedef int Element;
struct Node
{
Element Data;
struct Node *Next;
};
typedef struct Node* Position;
typedef Position List;

Pointer in typedef struct

I came across a stack tutorial in the C language and I can't seem to understand what the *Stack pointer is pointing towards nor the *next pointer.
I would just like to have a quick explanation on what these two pointers actually point to.
typedef struct StackElement
{
int value;
struct StackElement *next;
}StackElement, *Stack;
Neither points to anything in the example you've given. This code is just the declaration of the structure type itself. You could break the typedefs out into maybe simpler form:
struct StackElement
{
int value;
struct StackElement *next;
};
typedef struct StackElement StackElement;
typedef struct StackElement *Stack;
That is, there is a declaration of the structure itself, which contains a field next to be used by the implementation code of this stack. That field, when filled in, will point to another struct StackElement structure.
The typedef parts just make convenience names - StackElement can be used in place of struct StackElement, and Stack can be used instead of struct StackElement *.

Linked list Implementation in C with structure

I'm using this structure as a linked list:
typedef struct Node{
int value;
struct node_t* next;
}node_t;
And everything works fine until I put struct node_t* next before int value field, then I have a lot of trash values working with that structure.
Is it about wrong implementation or something else in the code?
You are calling your structure Node and defining a node_t type. Then you are using node_t as if it was the name of the structure and not the type.
Try this
typedef struct node {
int value;
struct node *next;
} Node;
Or
typedef struct node Node;
struct node {
int value;
Node *node;
};
If you call it struct Node, then
struct Node {
int value;
/* The compiler doesn't know what `struct Node' is yet */
struct Node *next;
/* But you can always declare pointers, even of types the compiler
* doesn't know everything about. Because the size of a pointer
* does not depend on the type of the pointee.
*/
};
In your example, it's even worse. You typedefed something that is a new type as the compiler understand it, to use it you MUST not use struct. The whole idea behind typedefing is that you DEFINED a new type, so suppose the following
typedef struct Node node;
then to declare a pointer of type node (note, again node IS A TYPE),
node *anode;
but you attempted something like
struct node *anode;
and it's wrong because there is no struct node in the code above, it's struct Node.
Another mistake in your code is that, the node_t type does not exist when the compiler finds the
struct node_t *next;
which is already wrong because if the type were defined before the struct which is possible like this
typedef struct Node node_t
it'd still be wrong to use struct on the node_t type, because for the compiler node_t is not a struct it's a new type, which in turn is simply an alias for struct Node.
Typedefing structures in my experience is more trouble than benefit anyway. And it's not so hard to type struct Something instead of just Something. It also has the benefit of being more explicit, so if another programmer reads your code, they will immediately know that Something is a struct.
Note: I deliberately changed the name to node because it's considered bad practice to suffix your own defined types with _t. It's not necessarily a bad thing, but over the years that I've been working with this I developed some habits and one of them is not to use _t as a suffix for my own defined types. Which by the way only exist in my code if they will improve readability a lot. Otherwise I simply use the name of the structure with the struct keyword.
You are using a non existing type node_t. The type doesn't exist because the type struct Node is not even complete and you are using it's alias. Another thing to remember while using typedefs with structures don't use struct keyword along with alias
eg.
/* This is correct */
typedef struct Node
{
int x;
struct Node *next;
} node_t;
/* while these are incorrect */
/* Prefixing struct keyword to a typedef'ed type */
struct node_t *listhead;
/* The type is inclomplete and you are using an alias of the type
which doesn't even exist */
typedef struct Node
{
int x;
node_t *next;
};
You are trying to create a pointer to the structure which you are yet to create. So, it should have been,
typedef struct Node{
int value;
struct Node* next;
}node_t;

Next struct item,incomplete type [duplicate]

This question already has answers here:
self referential struct definition?
(9 answers)
Closed 6 years ago.
struct node{
struct node next;
int id;
}
gives "field next has incomplete type error ".
what is wrong with this struct ?
When creating a self-referential data type, you need to use pointers to get around problems of circularity:
struct node;
struct node {
struct node * next;
int id;
}
...should work, but take care to allocate memory correctly when using it.
Why a pointer? Consider this: the point of a struct definition is so that the compiler can figure out how much memory to allocate and what parts to access when you say node.id. If your node struct contains another node struct, how much memory should the compiler allocate for a given node?
By using a pointer you get around this, because the compiler knows how much space to allocate for a pointer.
If a struct could contain another instance of its own type, its size would be infinite.
This is why it can only contain a pointer to its it own type.
Furthermore, at that point in code, the size of the struct is unknown, so the compiler couldn't know how much space to reserve for it.
You need to do a forward-declaration of node, since the compiler doesn't know node yet while it's processing its definition.
You probably meant to store a pointer, not a node object itself.
Try this:
struct node;
struct node{
struct node *next;
int id;
};
Some uses of incomplete types are ill-formed, such as when you try to declare an object of an incomplete type. However, you can declare a pointer to an incomplete type (for example). In this case that is just what is needed here:
struct node{
struct node *next;
int id;
};
The problem is, when the compiler reaches this line:
struct node{
struct node next; /* << this line */
the compiler actually doesn't know what is struct node, because you're defining struct node.
In general, you cannot use a type which is not defined or incomplete.
In order to work, you should write:
typedef struct _node{
struct _node* next;
int id;
}node;

self referential struct definition?

I haven't been writing C for very long, and so I'm not sure about how I should go about doing these sorts of recursive things... I would like each cell to contain another cell, but I get an error along the lines of "field 'child' has incomplete type". What's up?
typedef struct Cell {
int isParent;
Cell child;
} Cell;
Clearly a Cell cannot contain another Cell as it becomes a never-ending recursion.
However a Cell CAN contain a pointer to another Cell.
typedef struct Cell {
bool isParent;
struct Cell* child;
} Cell;
In C, you cannot reference the typedef that you're creating withing the structure itself. You have to use the structure name, as in the following test program:
#include <stdio.h>
#include <stdlib.h>
typedef struct Cell {
int cellSeq;
struct Cell* next; /* 'tCell *next' will not work here */
} tCell;
int main(void) {
int i;
tCell *curr;
tCell *first;
tCell *last;
/* Construct linked list, 100 down to 80. */
first = malloc (sizeof (tCell));
last = first;
first->cellSeq = 100;
first->next = NULL;
for (i = 0; i < 20; i++) {
curr = malloc (sizeof (tCell));
curr->cellSeq = last->cellSeq - 1;
curr->next = NULL;
last->next = curr;
last = curr;
}
/* Walk the list, printing sequence numbers. */
curr = first;
while (curr != NULL) {
printf ("Sequence = %d\n", curr->cellSeq);
curr = curr->next;
}
return 0;
}
Although it's probably a lot more complicated than this in the standard, you can think of it as the compiler knowing about struct Cell on the first line of the typedef but not knowing about tCell until the last line :-) That's how I remember that rule.
From the theoretical point of view, Languages can only support self-referential structures not self-inclusive structures.
There is sort of a way around this:
struct Cell {
bool isParent;
struct Cell* child;
};
struct Cell;
typedef struct Cell Cell;
If you declare it like this, it properly tells the compiler that struct Cell and plain-ol'-cell are the same. So you can use Cell just like normal. Still have to use struct Cell inside of the initial declaration itself though.
I know this post is old, however, to get the effect you are looking for, you may want to try the following:
#define TAKE_ADVANTAGE
/* Forward declaration of "struct Cell" as type Cell. */
typedef struct Cell Cell;
#ifdef TAKE_ADVANTAGE
/*
Define Cell structure taking advantage of forward declaration.
*/
struct Cell
{
int isParent;
Cell *child;
};
#else
/*
Or...you could define it as other posters have mentioned without taking
advantage of the forward declaration.
*/
struct Cell
{
int isParent;
struct Cell *child;
};
#endif
/*
Some code here...
*/
/* Use the Cell type. */
Cell newCell;
In either of the two cases mentioned in the code fragment above, you MUST declare your child Cell structure as a pointer. If you do not, then you will get the "field 'child' has incomplete type" error. The reason is that "struct Cell" must be defined in order for the compiler to know how much space to allocate when it is used.
If you attempt to use "struct Cell" inside the definition of "struct Cell", then the compiler cannot yet know how much space "struct Cell" is supposed to take. However, the compiler already knows how much space a pointer takes, and (with the forward declaration) it knows that "Cell" is a type of "struct Cell" (although it doesn't yet know how big a "struct Cell" is). So, the compiler can define a "Cell *" within the struct that is being defined.
Another convenient method is to pre-typedef the structure with,structure tag as:
//declare new type 'Node', as same as struct tag
typedef struct Node Node;
//struct with structure tag 'Node'
struct Node
{
int data;
//pointer to structure with custom type as same as struct tag
Node *nextNode;
};
//another pointer of custom type 'Node', same as struct tag
Node *node;
Lets go through basic definition of typedef. typedef use to define an alias to an existing data type either it is user defined or inbuilt.
typedef <data_type> <alias>;
for example
typedef int scores;
scores team1 = 99;
Confusion here is with the self referential structure, due to a member of same data type which is not define earlier. So In standard way you can write your code as :-
//View 1
typedef struct{ bool isParent; struct Cell* child;} Cell;
//View 2
typedef struct{
bool isParent;
struct Cell* child;
} Cell;
//Other Available ways, define stucture and create typedef
struct Cell {
bool isParent;
struct Cell* child;
};
typedef struct Cell Cell;
But last option increase some extra lines and words with usually we don't want to do (we are so lazy you know ;) ) . So prefer View 2.
A Structure which contain a reference to itself. A common occurrence of this in a structure which describes a node for a link list. Each node needs a reference to the next node in the chain.
struct node
{
int data;
struct node *next; // <-self reference
};
All previous answers are great , i just thought to give an insight on why a structure can't contain an instance of its own type (not a reference).
its very important to note that structures are 'value' types i.e they contain the actual value, so when you declare a structure the compiler has to decide how much memory to allocate to an instance of it, so it goes through all its members and adds up their memory to figure out the over all memory of the struct, but if the compiler found an instance of the same struct inside then this is a paradox (i.e in order to know how much memory struct A takes you have to decide how much memory struct A takes !).
But reference types are different, if a struct 'A' contains a 'reference' to an instance of its own type, although we don't know yet how much memory is allocated to it, we know how much memory is allocated to a memory address (i.e the reference).
HTH

Resources