Why can't a struct be a member of itself? - c

I have a struct foo. Declaring a member of type foo* works:
typedef struct foo
{
struct foo* children[26];
} foo;
But if I try to declare a member of type foo I get an error:
typedef struct foo
{
struct foo children[26];
} foo;
This declaration gives me the error
definition of 'struct foo' is not complete until the closing '}'

A structure T cannot contain itself. How would you know its size? It would be impossible to do so, because the size of T would require you to know the size of T (because T contains another T). This turns into an infinite recursion.
You can have a pointer to T inside a structure T because the size of a pointer is not the same size as the pointed-to object: in this case, you would just store an address of memory where another T is stored - all the space you need to do that is basically the space you need to store a memory address where another T lives.

The structure Trie cannot contain another structure Trie in it , it will do a never - ending recursion but it may contain a pointer to another structure Trie
So first one is correct
typedef struct TRIE
{
bool is_endpoint;
bool is_initialized;
struct TRIE* children[26];
} TRIE;

Object of type T can't contains another non-static object of same type. If it may be possible, how to find size of that object? Size of pointer to object is always constant on current system.
Check value of currentptr for non-NULL before you can access fields of currentptr (like is_endpoint).

Related

How to decode struct pointer with function?

I know how struct pointers work in general. But for struct spi_controller * spi_busnum_to_master(u16 bus_num),
What is holding the address of the struct spi_controller it is pointing towards ?
Can someone decode the logic of this declaration?. ( this style creating struct pointers)
From my understanding, a struct pointer is to enable a variable hold the address of some structure that it points to.
struct spi_controller * spi_busnum_to_master(u16 bus_num) declares spi_busnum_to_master to be a function taking a parameter of type u16 and returning a pointer to struct spi_controller.
The return value is passed by whatever method is defined by the Application Binary Interface for the target platform. Often it is in a processor register.

Pointers to structures when declaring structure inside a structure

I have a question regarding structures definition and pointers.
In the definition of linked list node structure we define the structure as follows:
typedef struct node
{
int data;
struct node *next;
}Node;
Why whould we use this way of declaration instead of:
typedef struct node
{
int data;
struct node next; //changed this line
}Node;
Thanks in advance!
A structure is defined after its closing brace. Until it a structure has an incomplete type. But a definition of a structure requires that all its members except a flexible array shall have complete types.
So in this declaration
typedef struct node
{
int data;
struct node next; //changed this line
}Node;
the data member next has an incomplete type.
From the C Standard (6.7.2.1 Structure and union speciļ¬ers)
...The type is incomplete until immediately after the } that terminates
the list, and complete thereafter.
and
3 A structure or union shall not contain a member with incomplete or
function type (hence, a structure shall not contain an instance of
itself, but may contain a pointer to an instance of itself), except
that the last member of a structure with more than one named member
may have incomplete array type; such a structure (and any union
containing, possibly recursively, a member that is such a structure)
shall not be a member of a structure or an element of an array.
As for pointers then they always have complete types because their sizes are known.
Actually we do that because, we avoid the recursive call. Suppose think your second case. You call node inside a node itself. So what is the sizeof the node. sizeof(int) + sizeof(node). Then again for the node the size become sizeof(int)+sizeof(node). So this is a unstoppable recursive process. So we use the first case because avoid the recursive process. It just point to the object of same type structure.
The compiler needs to determine the size of whatever it is that comes its way.
This needs completeness in definition, so that a determined calculation can be made.
In the first case of self referential structure, we have a pointer. A pointer is os struct node * type has a definite size determined by the architecture.
In the second case - struct node next, what would be the size of next? Would it be the size of struct node? Okay, let's say it is, but then again - what is the size of struct node? Well, the answer is sizeof(int) + sizeof(struct node). Okay, but then again... wait...what??... go back and read this entire para again, and realize the catch-22 situation here...
The compilers won't and don't appreciate this!

Pointers on member of the structure

http://i64.tinypic.com/34ffxx2.jpg
Please have a look at that image. ( Link given above)
In the book, it is stated that the 'next' member of structure variable 'n1' will point to the 'value' member of structure variable 'n2'.
1:) Won't it point to the complete 'n2' structure since 'n2' is a structure variable and the 'next' pointer is pointing to 'n2' and not particularly to its 'value' member.
2:) Also, it is stated that it is completely fine for a structure to contain another structure with same name and data type. How's that possible? I get it we can have as many structures in a parent structure, but how come a member has a data type of the parent structure ?
Oups. The book is right, but your understanding is wrong...
n1.next actually points to n2. It just happens that value is the first member of the struct so it lies at same address as the whole struct
What is stated is that it is fine for a struct is that one of its elements points to another struct of same type. But it cannot contain it. This is a compilation error:
struct entry {
int value;
struct entry next; // Ouch, tries to contain self: ERROR!
};

Struct points as parameter to function C

I have a few months that i started programming in C, but I now find myself with a doubt, for example, let see the next example code:
typedef struct
{
char *var1;
}myFooStruct;
myFooStruct struct1 [ 200 ];
my doubt is what would I get for **struct1, &struct1, *struct1, struct1,
as I passed the struct to a function that takes a two-dimenssion pointer ( **myFooStruct ), I have basic knowledge about pointers 1-but I find myself confused with pointers to structs and 2-how can I modify the struct if I passed it as at parameter to a function
If there is another similar question post it here please, I could not find anything alike, if you know some lecture I could read is welcome too, thank you very much!!
* is a dereference operator - think of it as meaning "the value contained at location xyz".
& is a reference operator - think of it as meaning "the location in memory of variable xyz".
Accordingly:
myFooStruct struct1 is a physical structure - this is the actual object.
&struct1 is equivalent to the location in memory of struct1 - this is usually an address (like 0xf0004782). You'll usually see this used when passing by reference (see Wikipedia for more info) or when assigning to a pointer (which literally points to a location in memory - get it?).
*struct1 dereferences struct1 - that is, it returns the value contained at location struct1. In the example you give, this is invalid, as struct1 is not a pointer to a location in memory.
**struct1 is tricky - it returns the value contained at the location that is contained within struct1. In other words: struct1 points to a certain location in memory. At that location is the address of another location in memory! Think of it as a scavenger hunt - you go to a location, find a clue, and follow that to another location.
As to how to access structs: think of a struct as a box. When you have the box in front of you, you simply need to open it up and look at what's inside. In C, we do this using the . operator:
char *my_var = struct1.var1
When you don't have the box in front of you - that is, you have a pointer to the struct - you need to access the location the box is at before you can look at what's inside. In C, we have a shortcut for this - the -> operator:
myFooStruct *pointer_to_struct1 = &struct1
char *my_var = pointer_to_struct1->var1
//NOTE: the previous line is equivalent to:
// char *my_var = (*pointer_to_struct1).var1
Way 1 Using dynamic memory allocation. Generally used in linked list and all..
If you want to modify the struct in another function. first declare a pointer to a struct.
myFooStruct* struct1;
Allot memory for the struct
struct1 = malloc(sizeof(myFooStruct));
Send the address to the function
func1(struct1);
Receive it and access it to modify in the function.
void func(myFooStruct* struct1)
{
(*struct1).member1 = ...; // whatever you wanna do
...
Way 2
Declare a struct.
myFooStruct struct1;
Send the address of the struct to the function
func1(&struct1);
Receive it and access it to modify in the function.
void func(myFooStruct* struct1)
{
(*struct1).member1 = ...; // whatever you wanna do
...
If you need to access myFooStruct from function, you can define single pointer: fn( myFooStruct * st ). The you call the function with fn( struct1 ) and change values st[N].var1 = .... Double pointer may be necessary if your object is pointer with allocated memory, not static array as yours.
struct1 is just a table and to be speciffic it's just pointer to a place in the memory.
*struct1 would be thing, that is pointed by struct1, so it's a first struct in a table of structs.
But **struct1 won't be any string. First of all you do not allocate memory for string and second string is member of this struct not struct itself. **struct is undefined behavior, nothing more.
&struct is a pointer to the table, so it's a pointer to the pointer, that points first struct in a table.
You have to decide on your own, what you want. If you want to pass table of your structs then the cleanest way would be:
void function(myFooStruct structTab[]);
1. You should pass a struct pointer to function to access struct inside it .
Declare a struct pointer -
myFooStruct *struct1;
Allocate memory for struct
And pass it to function which is declared as -
type fn(myFooStruct *struct1){
.....
}
Call this function like this -
fn(struct1);
Access struct member like this -struct->member1
2. You can also pass what you have declared right now.
myFooStruct struct1[ 200 ];
define function as -
type fn(myFooStruct struct1[]){
.....
}
Access struct members like this - struct[i].member1.

Arrow vs. Dot in C Structs?

I've got a specific question regarding the arrow vs. dot notation for structs in C. I understand that -> is used for struct pointers, and . is used for objects, however I've been having some trouble parsing some code I found online.
typedef struct node{
int data;
}Node;
typedef struct heap{
int size;
Node *dataArray;
}Heap;
typedef struct plan{
int maxPile;
Heap *heapArray;
}Plan;
Given this code, if I create:
Plan *p
And then I want to access a specific index in the heapArray inside Plan I would do:
p->heapArray[i]
From here, though if I want to access either the size of the dataArray inside a struct heap, would I use '->' or '.'?
So if I wanted to get the first element of the data array of that heap would I do:
p->heapArray[i].dataArray[0]
or
p->heapArray[i]->dataArray[0]
The correct answer is
p->heapArray[i].dataArray[0]
because when you use the subscript on the heapArray pointer, it's like doing pointer arithmetic and then dereferencing the pointer, something like this
(*(p->heapArray + 1)).dataArray[0]
so when you dereference it, the type of it becomes Heap which means it's not a pointer and has to be accessed with a . and not a ->.
p->heapArray[i] is of type Heap, which is a struct, so you'd use ..

Resources