C, How to acess a structure from another structure? - c

I am getting an error:
error: request for member ‘clsf_ptr’ in something not a structure or union
From this C Program:
#include<stdio.h>
#define M 3
struct class_stud
{
char name[16];
char subject[16];
int roll_num;
}
struct node
{
int n;
struct branch *p[M];
struct class_stud cls[M-1];
}*root=NULL;
main()
{
int clsf_cnt;
struct class_stud clsf, *clsf_ptr;
clsf_ptr = &clsf;
clsf_cnt = 0;
root = malloc(sizeof (struct node));
printf("enter source address \n");
scanf("%s",&root.clsf_ptr[clsf_cnt]->name);
printf("%s",root.clsf_ptr[clsf_cnt]->name);
printf("enter key\n");
scanf("%d",&root.clsf_ptr[clsf_cnt]->key);
printf("%d",root.clsf_ptr[clsf_cnt] -> key);
clsf_cnt++;
}
What does the error mean?

There are a number of problems in this code. Let's walk through it line by line:
#include<stdio.h>
#define M 3
struct class_stud
{
char name[16];
char subject[16];
int roll_num;
}
First problem; you need a closing ; after the struct definition above. Also, it's interesting that you don't define a preprocessor macro for the lengths of the name and subject arrays, but that's a minor issue at this point.
struct node
{
int n;
struct branch *p[M];
struct class_stud cls[M-1];
}*root=NULL;
Where is the definition for struct branch? What is p supposed to represent in the structure definition? Why do you have one fewer elements in cls than p?
main()
As of C99, you cannot get away with an implicit type for main; it must be explicitly typed to return int. And, since you're not messing with any command-line arguments, it's best to explicitly set the parameter list to void, like so:
int main(void)
{
int clsf_cnt;
struct class_stud clsf, *clsf_ptr;
clsf_ptr = &clsf;
What purpose does the above operation serve?
clsf_cnt = 0;
root = malloc(sizeof (struct node));
That's fine, but a preferred way of writing this would be
root = malloc(sizeof *root);
That way you're sure to allocate the right amount of memory based on root's type.
printf("enter source address \n");
scanf("%s",&root.clsf_ptr[clsf_cnt]->name);
Ack. Multiple problems in this one line.
First of all, clsf_ptr is not a member of struct node. You likely meant to access cls. Secondly, since root is a pointer to struct, you need to use the -> operator to access its members (or explicitly dereference root and then use .). Third, cls[clsf_cnt] is not a pointer type, so you would use the . operator to access name. Finally, since name is an array type, it will implicitly be converted to a pointer type before being passed to scanf, so the & isn't necessary.
In order to avoid buffer overflow, you should either put a maximum field width in the %s conversion specifier, or use fgets() instead of scanf().
Sticking with scanf(), that line should be written as
scanf("%15s", root->cls[clsf_cnt].name);
I'm using 15 instead of 16 in the conversion specifier so that we leave one character for the 0 terminator.
Using fgets(), that line would be written
fgets(root->cls[clsf_cnt].name, sizeof root->cls[clsf_cnt].name, stdin);
printf("%s",root.clsf_ptr[clsf_cnt]->name);
Again, you're trying to access something that isn't a member of root, and you have your access operators backwards:
printf ("%s", root->cls[clsf_cnt].name);
printf("enter key\n");
scanf("%d",&root.clsf_ptr[clsf_cnt]->key);
printf("%d",root.clsf_ptr[clsf_cnt] -> key);
struct class_stud has no member named key; perhaps you meant roll_num?
scanf("%d", &root->cls[clsf_cnt].roll_num);
printf("%d", root->cls[clsf_cnt].roll_num);
clsf_cnt++;
}
It looks like you've posted something that isn't complete; make sure you're showing us the same code you're trying to build.

Any instance of root.clsf_ptr you have in your code should be replaced with root->clsf_ptr, which indicates that root is a pointer to a struct.
You also need to make sure the member clsf_ptr is located in the node struct.

Here is some general source code cleanup that may be helpful:
#include <stdio.h>
#define M 3
typedef struct
{
char name [16];
char subject [16];
int roll_num;
} Class_stud;
typedef struct
{
int n;
Branch* p[M];
Class_stud cls[M-1];
} Node;
int main()
{
Node* root;
int clsf_cnt;
Class_stud clsf;
Class_stud* clsf_ptr;
clsf_ptr = &clsf;
clsf_cnt = 0;
root = malloc (sizeof(Node));
if(root == NULL)
{
/* error handling here */
}
}

The following code should work for you. I'm assuming key should be a member in class_stud (and by your formatting options in scanf, a signed integer):
#include<stdio.h>
#define M 3
typedef struct
{
char name[16];
char subject[16];
int roll_num;
int key;
} class_stud;
typedef struct
{
int n;
struct branch *p[M];
struct class_stud cls[M-1];
} node;
int main(void)
{
int clsf_cnt = 0;
node *root;
root = malloc(sizeof(node));
if (root == NULL) {
/* handle error */
}
printf("enter source address \n");
scanf("%s",&root->cls[clsf_cnt]->name);
printf("%s",root->cls[clsf_cnt]->name);
printf("enter key\n");
scanf("%d",&root->cls[clsf_cnt]->key);
printf("%d",root->cls[clsf_cnt]->key);
clsf_cnt++;
}
You had the following problems:
Incorrectly accessing class_stud. It's a part of root, so you want root -> class_stud[member]->value.
key was omitted
Both were changed to typedefined structures as shown in Lundin's answer, however you need not make them types (just using struct is fine).
We just declare root to be a pointer to node, rather than declaring struct node, and then a pointer and then making the assignment.
We aren't creating a structure as a pointer, we're creating a pointer to a structure
Main should return the type int, if you don't want arguments, tell the compiler that you expect argc to be void.
Stuff I didn't do:
Initialize the allocated structure with memset() or via calloc()
Handle malloc() failing
Compile my example (I don't know what struct branch is)

I think malloc syntax is wrong. once check that. Memory is not allocated.Thats why it shows an error.

Related

Can you create an array of Structure inside of another structure in C language?

Aim : To create a structure of element having certain properties. Then utilize that structure type by creating it's array in another structure.
struct Element
{
int i;
int j;
int x;
};
struct Sparse
{
int r;
int c;
int n;
struct Element *ele;
ele = (struct Element *)malloc(n*sizeof(struct Element));
};
What I wish to know is that which part of the code am I not allowed to write while creating a structure.
The common way to do this is:
struct Element
{
int i;
int j;
int x;
};
struct Sparse
{
int r;
int c;
int n;
struct Element ele[0]; // Make a zero length array
};
struct Sparse* MakeNewSparse(size_t num_ele)
{
struct Sparse* sparse = malloc(sizeof(*sparse) + num_ele*sizeof(struct Element));
return sparse;
}
This works because accessing off the end of a zero-length array is totally legal in C, provided you have allocated memory there.
In this example, we allocate enough space for the struct Sparse, and then enough more contiguous space for the array of struct Element.
After that, accessing element sparse->ele[5] is totally legal.
The line
ele = (struct Element *)malloc(n*sizeof(struct Element));
should not be part of the struct definition - that's something you do at runtime, along these lines:
struct Sparse s; // create new struct Sparse instance
s.n = get_some_size();
s.ele = malloc( s.n * sizeof *s.ele ); // no need for cast
struct in c is syntactically similar with types like int, char, etc. The definition of a struct is for compiler to know how to use variable declared with that struct such as struct Sparse var;. So the definition of a struct is not actually the code itself. It will be used at compile time.
However, malloc() is a function, which will be used at runtime, so it is nonsense to put malloc() in your struct definition.

Getting value from struct by pointer to pointer in C

I'm making a program in C. Basically I have a struct that contains some fields, and an array of pointers. Each struct has an pointer array that points to another struct forming a "connection" between them. I'm trying to get the value of a field that is stored at the memory address the pointer that is pointing at it.
Suppose this. I have two of these nodes in memory. A and B. A has a pointer inside A's array that is a reference to B. To get this pointer I'd have to do something like this:
*temp_ptr = (*ptr).pointer_array[0]
This would get the pointer address *ptr and give it to *temp_ptr.
Now what I am wondering is this. How can i do this? When I try this, I get "Expression must have struct or union type"
When I try this in lets say Java I could do this
int variable = field[0].fieldIWantToGet
I'd get the desired outcome.
Heres an image to clarify the intended behaviour that I'm trying to get. Link to behavior
Where Struct A is in a "global" collection of structs and has a array of pointers that lead to other Structs, such as B
Here is some code from my project.
#define GLOBAL_PTR_ARRAY_SIZE 10
Node* global_node_array[10];
typedef struct Node{
unsigned char node_id;
int *ptr_array[10];
int ptr_array_size;
}Node;
void append_connection(short position, short destination) {
Node* position_ptr = global_node_array[position];
Node* destination_ptr = global_node_array[destination];
if ((*position_ptr).ptr_array_size < GLOBAL_PTR_ARRAY_SIZE) {
int current_ptr_array_size = (*position_ptr).ptr_array_size;
(*position_ptr).ptr_array[current_ptr_array_size] = destination_ptr;
(*position_ptr).ptr_array_size++;
}
void print_id(Node* ptr) {
node* dptr = NULL;
dptr = ptr->ptr_array[0];
pptr = (int) (*ptr).ptr_array[0];
fprintf(stdout, "%d connection to %d exists", (*ptr).node_id, dptr-
>node_id);
}
int main(int argc, char const *argv[])
{
append_connection(0,1);
print_id(global_node_array[0]);
return 0;
}
Your picture shows array of the structs not the pointers. But the example below covers both.
struct a{
int field1,field2;
}
struct b{
struct a m[10];
}
struct c{
struct a *m[10]
}
/* and usage */
struct c *x;
struct b *y;
x -> m[5].field1;
y -> m[5] -> fileld1;

C language and Queues/linked lists

Can someone please explain the code below. I am new to C and trying to figure it out. why do we have queueNodeT at the end?
typedef char queueElementT;
typedef struct queueNodeTag {
queueElementT element;
struct queueNodeTag *next;
} queueNodeT;
queueNodeT is the name of the type that the typedef statement is trying to create.
An alternate way to specify this is:
struct queueNodeTag {
...
};
typedef struct queueNodeTag queueNodeT;
In C (vs. C++), "struct queueNodeTag" just defines a struct named "queueNodeTag". In C++ [should you get there], this would also define a type named "queueNodeTag"
When creating a pointer variable to the struct, it's slightly shorter to use:
queueNodeT *my_pointer;
than:
struct queueNodeTag *my_pointer;
The trailing "T" is just a coding convention to denote that it's a type name and not a variable. You can use others. Mine is:
struct mystructname {
...
};
typedef struct mystructname mystructname_t;
typedef mystructname_t *mystructname_p;
Using mystructname_p, you can change:
struct mystructname *my_pointer;
mystructname_t *my_pointer;
into:
mystructname_p my_pointer;
The "_t" is fairly common. The "_p" thing is my convention, but, I believe other conventions define pointers to types as "p<Mytype>", such as "pMystructName". I much prefer using a suffix for this [and "snake case" notation rather than the "camel hump" notation in your example].
Let's break it down part by part.
This line simply tells you that queueElementT is defined as char here. Meaning you can write either queueElementT or char, both will work.
typedef char queueElementT;
Now here is the actual struct. It contain two variables, the element it is holding, in this case a char. It then also tells which element is next in the queue.
typedef struct queueNodeTag {
queueElementT element;
struct queueNodeTag *next;
} queueNodeT;
More of that can be read in this answer.
A demonstration:
int count (queueNodeTag q) {
int i = 0;
if (q == null) {
return 0;
}
if (q.next == null) {
return 1;
}
while (q.next != null) {
q = q.next;
i++;
}
return i;
}
Three cases to handle.
q is null, the queue is empty. Return 0.
q.next is null, the queue only contains one element. Return 1.
Repeat until q.next is separated from null, increment i as we go. A better name for i might be elements or something similar.
This code is untested as I currently do not have a C compiler at hand. Someone who has one available can perhaps verify that no mistake has been done?

Understanding pointer structs in C

I am trying to understand an assignment I have before I have to take a final. I am trying to understand what exactly I am declaring.
So in a given file the typedef struct's are declared as so:
(Struct Declaration)
/** The following two structs must be defined in your <gamename>.c file **/
typedef struct game_position_t *game_position;
/* move struct must code enough information to reverse the move, given the resulting position */
typedef struct move_t *move;
I have then built the structs out as so (yes this has to be separated just because it is interfaced programming):
(Struct Definition)
/** The following two structs must be defined in your <gamename>.c file **/
struct game_position_t {
int mathy;
int numrows;
int *sizes;
};
/* move struct must code enough information to reverse the move, given the resulting position */
struct move_t {
int rownum;
int move_size;
};
Then an example of a functions and declaration of game_position for example is:
(Example Function)
/* return the starting position, NULL if error */
game_position starting_position(int me_first, int argc, char **argv) {
if (argc < 3) {
printf("\n\nToo few arguments, see help below\n\n");
game_help(argv[0]);
return NULL;
}
int mathy;
if (strcmp(argv[2],"search")==0)
mathy = 0;
else if (strcmp(argv[2],"mathy")==0)
mathy = 1;
else {
printf("\n\nSecond argument must be \"search\" or \"mathy\", see help below\n\n");
game_help(argv[0]);
return NULL;
}
int play_default = (argc==3);
if (play_default) printf("\n\nOK, we will play the default game of 7 5 3 1\n\n");
int defaultgame[4] = {7,5,3,1};
game_position result = malloc(sizeof(struct game_position_t)*1);
result->mathy = mathy;
if (result) {
result->numrows = (play_default ? 4 : argc-3);
result->sizes = malloc(sizeof(int)*(result->numrows));
int row;
for (row=0; row<(result->numrows); row++)
(result->sizes)[row] = (play_default ? defaultgame[row] : strlen(argv[row+2]));
}
return result;
}
So my main misunderstanding is when using a struct declaration in this manner, specifically putting the * before the name like this, typedef struct move_t *move;. Is that previous line saying move it a struct pointer or dereferencing move? Continuing from that. When defining them I just use the struct name such as struct move_t. I don't fully understand how they are linking together and in what matter. Then inside the function I just declare game_position, but still need to use a derefencer, 'p->`, to access it fields. So if someone could explain to me when these struct variables are points to structs and when they are the actual struct.
An example of my misunderstanding is that in the Example Function after result was declared. I first thought to use the . operator to access and set it's fields. I then changed it due to compiler errors, but now I want to understand my misunderstanding. And why did I I have to malloc game_position_t and not game_position?
typedef defines a type, so typedef struct move_t *move defines a new type named move, which is a pointer type, pointing to struct move_t. So after this if you define a variable with move ptr, ptr will have a pointer type so that you should use the syntax of accessing members through a pointer. When allocating memory for it, of course you have to specify the exact size of the structure other than the size of a pointer, that's sizeof(struct move_t)

pointer to struct in struct in c

I have trouble with structures in c.
I have two structures like
typedef struct
{
char isim[256];
int deger;
struct ekstra *sonra;
}ekstra;
typedef struct
{
char *name;
int val;
struct ekstra *next;
}node;
/*and main is*/
int main()
{
int i;
node dizi[12];
for(i=0;i<12;i++)
{
dizi[i].name = malloc("asdasd"*sizeof(int));
strcpy (dizi[i].name,"asdasd");
/*and trouble starts here*/
**dizi[i].next = malloc(sizeof(ekstra));
printf("%s",dizi[i].next->isim);**
}
}
the error is
error: dereferencing pointer to incomplete type
How can I hold place for dizi[i].next?
struct ekstra is not the same as ekstra.
Your first struct typedef should be declared as follows:
typedef struct ekstra
{
char isim[256];
int deger;
struct ekstra *sonra;
}ekstra;
typedef struct... ekstra;
This means: "create a type that is called ekstra". From now on this type can be used just as any variable type (int, char etc).
struct ekstra *next;
This means: Somewhere in my program there is a struct of some type, I don't know what it contains, but I want to point to an element of that type. This is the meaning of incomplete type.
To fix your problems, simply replace this row with ekstra *next;.
More comments not directly related to the question:
dizi[i].name = malloc("asdasd"*sizeof(int));
This is pure nonsense code. It means: "Create a constant string literal in the ROM part of my program. In this constant string literal, store the letters "asdasd" and a null termination character. Then take the address of this ROM memory location, which is completely irrelevant to my application, convert it to an integer so that I get a 32-bit nonsense number. Then multiply this nonsense number with the sizeof an int, which doesn't make any sense to anyone either. Then take this completely nonsense result and allocate a random amount of dynamic memory based on this. Then watch the program crash.
I don't understand code line like
malloc("asdasd"*sizeof(int));
But, I think you problem should slove like this
dizi[i].next = (ekstra *)malloc(sizeof(ekstra));
and you struct define should like
typedef struct node{
int a;
int b;
struct node *next;
}node;

Resources