I'm working on (very slowly) reverse engineering a PS2 game that was programmed in C, and I've found that there is a struct of a certain type that, among other things, contains a pointer of that struct type whose value is equal to the struct's address itself. A stripped down version (apologies if syntax is incorrect, still learning that):
struct gObj {
gObj* self;
int visible;
gObj* next;
gObj* prev;
};
int main() {
gObj* player;
player = (gObj*)malloc(sizeof(gObj));
player->self = &player;
player->visible = 1;
};
I've done some googling, and I get self-referencing struct discussions for linked lists, but no real answers as to why an instance would reference itself. The game does use the self member by using it to reference the other members of the instance, but why not just access those members directly from the base pointer of the instance? Maybe it's just some quirk of the programmers themselves that they implemented the struct that way.
You need to do it in this order:
typedef struct Node Node;
struct Node
{
int value;
Node *next;
Node *prev;
};
That doesn't do exactly what you asked, but it solves the problem and is how this generally is done. I don't think there's a better way.
This kind of forward declaration has a second usage, in data hiding. If the list was implemented in a library, you could have just the typedef in the public header, along with functions like:
Node * list_new(void);
Node * list_append(Node *head, Node *new_tail);
size_t list_length(const Node *head);
This way, users of the library don't have easy access to the internals of your library, i.e. the fields of the Node structure.
Another acceptable way and with the least change to OP's code is the following:
typedef struct NodeT {
int value;
struct NodeT * next;
struct NodeT * prev;
} Node;
Note the introduction of NodeT and its usage in next and prev until Node is available.
Yes, but you have to name the structure, so that you can refer to it.
typedef struct node_ {
char* name;
struct node_ * parent;
} node;
The name node only becomes declared after the structure is fully defined.
You can use an incomplete type in the typedef:
typedef struct node node;
struct node {
char *name;
node *parent;
};
You can use a forward declaration of the struct
typedef struct sNode Node; // this is a typedef and a declaration of the struct
struct sNode{
int data;
Node *next;
Node *prev;
};
This way Node is known (but not defined), in the definition of your struct.
This can be compressed as it is done by Yunnosch. But then you need to use the struct Name notation inside your declaration.
This way it is possible to already use the typedefed name also the forward declaration is necessary if you have some circular dependencies in your structs.
It is also possible to use the struct name as the typedef:
typedef struct Node Node;
struct Node{
int data;
Node *next;
Node *prev;
};
I personally prefer the first style, it seems "clearer" to me, but there is nothing wrong with the second example, as long as the compiler is not from the pre-standard era (before 1989).
As Jens Gustedt pointed out the first style might be incompatible if this is included in C++.
So maybe I should change my preference to the first.
Inside the typedef, the to-be-defined type is not yet known, so you need to introduce and use a struct tag:
typedef struct Node_tag {
int data;
struct Node_tag *next;
struct Node_tag *prev;
} Node;
The Node_tag is the struct tag, because of where it is introduced (and not because of the name part "_tag"). It is not a type in itself, only the combination as struct Node_tag is a type which can be used for the struct members.
Afterwards, when the typedef is done, the type Node has been defined.
To clarify, a second typedef would be possible as typedef struct Node_tag NodeToo;. This demonstrates that the type struct Node_tag is also useable. That is why I prefer to use the "_tag" name fragment, to allow to be clear of what is used.
Are you asking which is better?
It depends what you are trying to do - the second form with a pointer will be more efficient. But if you just want to pass a value to f and not have to worry about side-effects then you might go with the first signature - as long as the struct is not too large.
I would suggest reading this.
When struct sis of decent size as you say, then you should avoid passing it by value, especially in recursive functions.
Passing a struct by value means that it gets copied before the function invocation. That results in slower execution and greater memory utilization. Also note that the struct is going to be allocating in the stack and in some systems the stack size is pretty limited.
I would suggest using a pointer in every case unless you need multiple copies of a structure to be modified by functions and you don't want those modifications only visible within each function's scope.
You can define the typedef and forward declare the struct first in one statement, and then define the struct in a subsequent definition.
typedef struct A A;
struct A
{
int a;
int b;
A* next;
};
Edit: As others have mentioned, without the forward declaration the struct name is still valid inside the struct definition (i.e. you can used struct A), but the typedef is not available until after the typedef definition is complete (so using just A wouldn't be valid). This may not matter too much with just one pointer member, but if you have a complex data structure with lots of self-type pointers, may be less wieldy.
In addition to the first answer, without a typedef and forward declaration, this should be fine too.
struct A
{
int a;
int b;
struct A *next;
};
I am a newbie to C. I recently learned about pointers and am comfortable with int pointers. However, I am having a hard time with structures.For instance, if I give a pointer to a structure how does the pointer point to all the data stored in the struct? How would that even be possible?Let me give an example -
int digit = 5 int *ptr = &digit; // Let's assume &digit is 1001 // Therefore ptr is now 1001
However, a structure is a contigous block of memory. What would a pointer to it store?