I have a struct that defined like that:
typedef struct my_struct
{
int numbers[10];
}
*my_struct;
Is there a way to find out its size?
sizeof(my_struct);// return size of a pointer
The struct type itself is spelled with struct, so you can say:
sizeof (struct my_struct)
This would not work if you hadn't also given your struct a name, which would have been possible:
typedef struct { int numbers[10]; } * foo; /* struct type has no name */
foo p = malloc(1000);
p->numbers[3] = 81;
I'd say all of this is poor code that is needlessly terse for no reason. I would just keep all the names unique, and name everything, and not alias pointers, for that matter. For example:
typedef struct my_struct_s my_struct;
my_struct * create_my_struct(void);
void destroy_my_struct(my_struct * p);
struct my_struct_s
{
int numbers[10];
};
Everything has a unique name, the typedef is separate from the struct definition, and pointers are explicit.
Related
i need to create a struct with an attribute that is a pointer to the same struct.
i'm trying this solution but not work:
typedef struct
{
int number;
void *other;
}mystruct;
extern mystruct first[];
extern mystruct second[];
mystruct first[] = {{1,NULL},{2,second}};
mystruct second[] = {{3,NULL},{4,first}};
mystruct *wrap;
wrap = (mystruct *)first[1].other;
int main(void){
printf("%d\n",first[0].number);
printf("%d\n",second[0].number);
printf("%d\n",wrap[1].number);
}
can someone help me?
best regards and thankyou
In C, you can name the struct before using it and typdefing it:
typedef struct mystruct_
{
int number;
struct mystruct_ *other;
} mystruct
I'm not entirely sure but are you looking for some sort of linked-lists or precisely speak Self Referential structure
struct list {
int something;
struct list *use_this_to_point_to_similar_type;
};
Here is another good reference what-is-self-referencing-structure-in-c
just a little bit simplification, and moving few instructions here and there, below code is a loosely written example of possibly what you are looking forward to achieve
#include<stdio.h>
struct mystruct
{
int number;
struct mystruct *other;
};
struct mystruct first[] = {{1,NULL},{2,NULL}};
struct mystruct second[] = {{3,NULL},{4,NULL}};
struct mystruct *wrap;
int main(void)
{
first[1].other = second;
second[1].other = first;
wrap = first[1].other;
printf("%d\n",first[0].number);
printf("%d\n",second[0].number);
printf("%d\n",wrap[1].number);
return 0;
}
your first and second don't need to be extern as they are allocated within your program. you can declare and init. var prior to the main. but the rest you must move into the main function:
int main(void){
wrap = (first[1].other);
printf("%d\n",first[0].number);
printf("%d\n",first[1].number);
printf("%d\n",second[0].number);
printf("%d\n",wrap[1].number);
return 0;}
I am still new in C. I know you can just use the already-declared struct as new data type such as int, double, etc. However, I encounter a struct written like this:
struct AdjListNode
{
int dest;
int weight;
struct AdjListNode* next;
};
In this struct, the data type of "next" pointer is struct AdjListNode*. What does struct have to do with the already-declared AdjListNode*? Thanks!
What does struct have to do with the already-declared AdjListNode*?
The answer is that the c syntax requires it.
You do not get a type AdjListNode by writing struct AdjListNode { ... };
AdjListNode is a struct tag and you always have to use struct AdjListNode when declaring variables.
See this simple example (without pointer inside the struct):
#include <stdio.h>
struct sSomeName
{
int x;
};
int main(void) {
struct sSomeName var; // OK, variable of type struct sSomeName
struct sSomeName* pVar; // OK, pointer to variable of type struct sSomeName
// sSomeName var2; // ERROR: unknown type name 'sSomeName'
var.x = 5;
pVar = &var;
printf("%d\n", pVar->x);
return 0;
}
So if you want to add a pointer inside the struct, you must write struct sSomeName just as you have to do inside main, i.e. like:
struct sSomeName
{
int x;
struct sSomeName* p;
};
Using typedef
If you want a type named AdjListNode you must use typedef.
A typedef example could look like:
#include <stdio.h>
typedef struct sSomeName sSomeName;
struct sSomeName
{
int x;
sSomeName* p;
};
int main(void) {
sSomeName var;
sSomeName* pVar;
var.x = 5;
var.p = NULL;
pVar = &var;
printf("%d\n", pVar->x);
printf("%p\n", (void*)pVar->p);
return 0;
}
Here with that declaration pointer to structure is declared. This is basically used for implementing linked list or for other data structures like tree.
It does'nt mean that struct is re-declared. It is similar to declare a struct variable.
The structure is created as follows: typedef struct AdjListNode. Example:
#include <stdio.h>
#include <stdlib.h>
typedef struct AdjListNode
{
int dest;
int weight;
struct AdjListNode* next;
}AdjListNode;
typedef struct Nodo{
char *nombre;
int *edad;
struct Nodo *siguiente;
}Nodo;
int main(int argc, char **argv) {
AdjListNode *nodo=malloc(sizeof(AdjListNode));
nodo->dest=1;
nodo->weight=2;
nodo->next=NULL;
printf("Nodo-->dest: %d", nodo->dest);
free(nodo);
}
I have two structures DirFileArray and dirFile that has variables of each other types. My Eclipse IDE is angry about that, because first structure does't see type of second one ('dirFile' could not be resolved). How to make both structures see each other?
struct dirFile;
I have added line at the top, put this does't help.
struct DirFileArray {
dirFile *array;
size_t used;
size_t size;
}
struct dirFile
{
int contentType ;
char name [STR_SHORT];
struct DirFileArray * content;
};
You need to "forward declare those arrays". Remember when you learned to use a function that would be later defined, what did you do? You would write:
int func_to_be_defined_later(int param); /* for example */
int main(void)
{
return func_to_be_defined_later(10);
}
int func_to_be_defined_later(int param)
{
return param + 1;
}
It's similar with structs:
/* forward declaration */
struct DirFileArray;
struct dirFile;
struct DirFileArray { /* note: you had misplaced the struct name */
struct dirFile *array; /* note: you forgot struct */
size_t used;
size_t size;
};
struct dirFile
{
int contentType ;
char name [STR_SHORT];
struct DirFileArray *dirFile;
};
It is worth noting that you can only point to forward declared structures (including the structure being declared) not have a variable of them. The reason is that the compiler knows how to allocate a pointer and how much space to give it, but it doesn't know how to allocate the struct and what is it's sizeof yet.
In fact, having two structs that contain a variable of the other's type, or a struct that contains a variable of its own type (not a pointer), is a bit of a contradiction. Try to think what would the sizeof such structs would be.
Use a forward declaration:
struct dirFile;
struct {
dirFile *array;
size_t used;
size_t size;
} DirFileArray;
struct dirFile
{
int contentType ;
char name [STR_SHORT];
struct DirFileArray * dirFile;
};
A simple forward declaration will do the trick.
You could look at typedef for a more complex include issue
struct dirFile;
struct {
dirFile *array;
size_t used;
size_t size;
} DirFileArray;
struct dirFile
{
int contentType ;
char name [STR_SHORT];
struct DirFileArray * dirFile;
};
If you really want to do this, use forward declaration.
typedef struct DirFileArray_s DirFileArray;
typedef struct dirFile_s dir_File;
struct DirFileArray_s {
...
}
struct DirFileArray_s {
...
}
I would suggest double think this though as such nesting is nasty.
Looked through many other SO posts related to this, but none were able to help me. So, I have the following structs defined:
typedef struct
{
int created;
double data;
int timeLeft;
int destination;
}dataPacket;
typedef struct
{
dataPacket *array;
int currIndex;
int firstIndex;
int nextTick;
int maxLength;
int length;
int stime;
int total;
}packetBuffer;
typedef struct{
int mac;
struct wire *lconnection;
struct wire *rconnection;
int numRecieved;
struct packetBuffer *buffer;
int i;
int backoff;
}node;
typedef struct{
float length;
float speed;
int busy;
struct dataPacket *currPacket;
struct node *lnode;
struct node *rnode;
}wire;
And then I'm trying to use the following function:
int sendPacket(node *n, int tick)
{
if(n->buffer->length > 0)
{
if(n->backoff <= 0)
{
if (n->lconnection->busy != 0 || n->lconnection->busy != 0)
{
n->i++;
n->backoff = (512/W * genrand()*(pow(2,n->i)-1))/TICK_LENGTH;
}
else
{
n->lconnection->busy = 1;
n->rconnection->busy = 1;
n->lconnection->currPacket = n->buffer[n->buffer->currIndex];
n->rconnection->currPacket = n->buffer[n->buffer->currIndex];
}
}
else
{
n->backoff--;
}
}
}
I'm getting the error described in the title everytime I try to access a member of buffer, lconnection, or rconnection.
struct packetBuffer *buffer;
You've defined a type packetBuffer (a typedef for an otherwise anonymous struct).
You haven't defined struct packetBuffer.
In the absence of an existing type struct packetBuffer, the compiler treats it as an incomplete type, assuming that you'll complete it later. The declaration
struct packetBuffer *buffer;
is perfectly legal, but you can't dereference buffer unless the type struct packetBuffer is visible.
Just drop the struct keyword.
(My personal preference is to drop the typedef and consistently refer to struct types as struct whatever, but that's a matter of style and taste.)
The following:
typedef struct {
int x;
char *y;
...
} my_struct;
creates an identifier for an anonymous structure. In order, for a structure to refer to an instance of itself, it must not be "anonymous":
typedef struct my_struct {
int x;
char *y;
struct my_struct *link
....
} my_struct_t;
This means that my_struct_t is now the type struct my_struct and not just an anonymous struct. Also, note that struct my_struct can be used within its own structure definition. That is not possible with anonymous structs.
As a final complication, the my_struct in struct my_struct is in a differenct "namespace" than the my_struct_t. This is sometimes used to to simplify (or confuse) things in code like this:
typedef struct my_struct {
int x;
char *y;
struct my_struct *link
....
} my_struct;
Now I can use my_struct anywhere in my code instead of struct my_struct.
Finally, you could separate the typedef from the structure definition to achieve the same effect:
struct my_struct {
int x;
char *y;
struct my_struct *link;
....
};
typedef struct my_struct my_struct;
As noted in David R.Hanson's C Interfaces and Implementations, "This definition is legal because structure, union, and enumeration tags occupy a same name space that is separate from the space for variables, functions, and type names."
What is the purpose of the following declaration?
struct test
{
int field1;
int field2[0];
};
That's simply a 0 length array. According to http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html:
Zero-length arrays are allowed in GNU C. They are very useful as the
last element of a structure which is really a header for a
variable-length object:
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
It's a zero size array, which is a useful GCC extension if you don't have C99.
It's for encapsulation.
It is used to create an interface without knowing any details.
Following is a simple example.
In test.h (interface), it shows that there is a struct test_t which has two fields.
And it has three function, first one is to create the structure.
set_x is to store some integer into the structure.
get_x is to get the stored integer.
So, when can we store x?
The person who is responsible for implement (test.c) will declare another structure which contains x.
And play some tricks in "test_create" to malloc this structure.
Once the interface and the implement have been done.
The application (main.c) can set/get x without knowing where it is.
test.h
struct test_t
{
int field1;
int field2[0];
};
struct test_t *test_create();
void set_x(struct test_t *thiz, int x);
int get_x(struct test_t *thiz);
test.c
#include "test.h"
struct test_priv_t {
int x;
};
struct test_t *test_create()
{
return (struct test_t*)malloc(sizeof(struct test_t) + sizeof(struct test_priv_t);
}
void set_x(struct test_t *thiz, int x)
{
struct test_priv_t *priv = (struct test_priv_t *)thiz->field2;
}
int get_x(struct test_t *thiz)
{
struct test_priv_t *priv = (struct test_priv_t *)thiz->field2;
}
main.c
#include "test.h"
int main()
{
struct test_t *test = test_create();
set_x(test, 1);
printf("%d\n", get_x(test));
}