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!
};
Related
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!
I am used to code like below for long.
But how does C compiler resolve the circular definition issue? Or does that issue really exist?
struct node {
int data;
struct node *next; // circular definition for "struct node" type?
};
ADD 1
Or, on a 32-bit machine, can I somewhat treat struct node * next member just as a member of 32-bit unsigned integer type? That makes me feel better.
ADD 2
The reason I think of circular definition is, when compiler encounters something like next -> data or next -> next, it has to know the exact offset of each member to add to the next pointer to get the correct location of each member. And that kind of calculation requires knowledge of each member's type. So for the member next, the circular definition issue may arise:
The type of next is struct node *, the struct node type
contains a next, the type of next is struct node *...
ADD 3
And how does the compiler calculate the sizeof(struct node)?
ADD 4
Well, I think the critical concept to understand this seemingly circular issue is, a pointer's size is not relevant to what type it points to. And the size is fixed on a specific machine. A pointer's type is only meaningful at compile-time for the compiler to generate instructions for pointer calculation.
next is a struct node *, which is just a pointer, not a struct node, so there's no actual circular definition. The details of a struct aren't required to figure out how to make a pointer to it.
To address your addenda:
Although that's more or less accurate and will probably work, it's not guaranteed by the standard, and you shouldn't do it.
Again, struct node and struct node * are entirely different types. A struct node * doesn't contain any other objects.
Let me answer your questions in order:
But how does C compiler resolve the circular definition issue?
struct node *next; is not a circular definition, struct node is an incomplete type, next is defined as a member with type struct node *, which is just a pointer.
Or does that issue really exist?
No, not really an issue. As a matter of fact, you could have members defined as pointers to any undefined structure.
Or, on a 32-bit machine, can I somewhat treat struct node *next member just as a member of 32-bit unsigned integer type?
You should not make any assumptions on the actual size, offset or alignment of structure members. A 32-bit machine could have pointers sizes that are not 32 bits, it does not matter as long as you use them as pointers, not integers.
The reason I think of circular definition is, when compiler encounters something like next->data or next->next, it has to know the exact offset of each member to add to the next pointer to get the correct location of each member.
That's correct, but by the time the compiler parses such code, the structure definition is complete and it can determine the offset of the data and next members.
And how does the compiler calculate the sizeof(struct node)?
After parsing the structure definition, the compiler has all the information needed to compute the size of structure instances. For such a computation, all pointers to structures and/or unions are assumed to have the same size.
Well, I think the critical concept to understand this seemingly circular issue is, a pointer's size is not relevant to what type it points to. And the size is fixed on a specific machine. A pointer's type is only meaningful at compile-time for the compiler to generate instructions for pointer calculation.
A pointer size is relevant to the type it points to, and on some architectures, different pointer types may have different sizes. Yet the C Standard specifies some constraints:
All pointer types can be converted to void * and back.
Pointers to all structures and unions have the same size.
On most modern architectures, and specifically on Posix compliant systems, all standard pointers types have the same size.
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.
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).
What is the difference between self referential pointer in structure and pointer to structure?
struct abc
{
int data;
struct abc *next;
}
struct abc *pt;
What are the differences between *next and *pt??
How they differ in their use??
I am really in doubt between these two
I am a beginner
First example is used mainly for linked list
Are pointer to structure node and self referential pointer the same thing?
please see
see-programming.blogspot.in/2013/05/chain-hashing-separate-chaining-with.html here we have used struct hash *hashTable as an array ..how?? and can we do same with *pt
They are of the same type. They behave in the exact same way.
Some example usage:
// declare 2 structs
struct abc s1;
struct abc s2;
// point pt to s1
pt = &s1;
// point s1.next to s2
s1.next = &s2;
// access pt->data
int a = pt->data;
// access s1.next->data
int a = s1.next->data;
Differences in usage:
There's only one pt variable.
For every struct abc variable, there is a next variable.
In the context of a linked-list, there is only one head pointer, thus pt would be it.
But each node points to the next node, thus next should be used for this.
Using pointers as arrays?
Yes, this can be done with either pt or next.
A pointer just points to an address in memory. There can be any number of structs following on each other at that location.
If you want to use it as an array (or just using pointers in general), you just have to make sure you don't try to access elements that you didn't allocate memory for (with malloc for example) and free the memory after usage (if you used malloc).
Some example usage with array:
// declare a struct
struct abc s1;
// make an array of size 10
struct abc *a1 = malloc(10*sizeof(struct abc));
// give the 4th element a new value
a1[4] = s1;
// free the memory
free(a1);
I hope that helps a bit.
Conceptually, very little difference at all.
next is a member of the same structure it is pointing to. pt is not a member of the structure it is pointing to.
They are used in a similar way, except that to use next you have a have an existing struct abc, and pt can be used directly. Please consider:
myABC.next= &myOtherABC ;
pt= &myOtherABC ;
are pointer to structure node and self referential pointer same thing
They are and they are not. Depends on point of view. They are because they both point to a structure. They are not because a pointer to structure can point to any structure, and as a variable it can be a parameter, a local variable, a member of another struct, etc. But a self referential pointer is necessarily a member of a struct and points to the same struct it is a member of.
The only difference applies to people that write compilers. That is because a self-referential pointer refers to itself before itself is fully declared. So someone writing a compiler has to deal with this special case.
As a programmer (that means you), there is no difference, and the terms do not offer any additional meaning.
they are the same type but they do not contain the same value
from pt you can access next because pt point to a structure that contain next. but from next you can't access pt.
for linked list, you have to understand, that the list contain at the begining 1 element, and this element know how reach the next element of the list, it is the goal of the next pointer
There is no difference between those two pointers.
A possible difference in usage depends on the context but still does not apply to their nature of being both pointer to the same type of structure and therefore undergoing the same rules in terms of assignment, reading and arithmetics.