Access struct in struct - c

I am working on a tree algorithm. These are the structures in my program:
typedef struct{
double m;
double x[DIM];
double v[DIM];
} Particle;
typedef struct{
double lower[DIM];
double upper[DIM];
} Box;
typedef struct Node{
Particle p;
Box box;
struct Node *son[4];
} Node;
Now I have written a function myFunctA() which is given by:
void myFunctA(Particle *p, Node *t){
int b=soNum(&t->box, &t->son->box, p); // Why does "&t->son->box" not work?
// do stuff ...
}
Within function myFunctA() I want to pass the box of t and the box of the son of t to the function soNum(). soNum() is given by
int soNum(Box *box, Box *sonbox, Particle *p){
// do stuff ...
}
I am trying to do this by using &t->son->box which does not work. I also tried (&t->son)->box. The error I get is always:
error: request for member ‘box’ in something not a structure or union
int b=soNum(&t->box, &t->son->box, p);
I think this is easy, but I am still quite new to C and find it somehow difficult to see it. I hope someone can help me!

Operator -> applies to a pointer, not to a struct. t is a pointer so t->son is correct. However, son is not a pointer, it is an array of pointers. Therefore
t->son->box
needs to be
t->son[someIndex]->box
where someIndex is an expression evaluating to an int between zero and three, inclusive.

t->son->box needs to be something like t->son[INDEX]->box (son is an array of node pointers).
This compiles:
#define DIM 3
typedef struct{
double m;
double x[DIM];
double v[DIM];
} Particle;
typedef struct{
double lower[DIM];
double upper[DIM];
} Box;
typedef struct Node{
Particle p;
Box box;
struct Node *son[4];
} Node;
int soNum(Box *box, Box *sonbox, Particle *p){
// do stuff ...
return 0;
}
void myFunctA(Particle *p, Node *t){
int b=soNum(&t->box, &t->son[0]->box, p); // Why does "&t->son->box" not work?
// do stuff ...
}

Related

C Passing Complex Structures by Reference to Functions

I replicated the guidance provided here but continue receiving the following error for each line with a function header and prototype: 'typedef "Neuron" may not be used in an elaborated type specifier'. I researched this error and didn't find much useful content. Any help would be most appreciated.
#include <stdio.h>
#include <stdlib.h>
struct neuronHead {
int x, y, z;
neuronHead *apical[25];
neuronHead *basal[25];
neuronHead *axon[25];
int time;
} neuron;
typedef struct neuron Neuron;
void setupBrain(struct Neuron ****brain); /* brain is a 3D array of structs */
void freeBrain(struct Neuron ****brain);
int main(void) {
Neuron ***brain;
setupBrain(&brain);
freeBrain(&brain); }
void setupBrain(struct Neuron ****brain) {
/* code for malloc'ing a 3D array of structures */ }
void freeBrain(struct Neuron ****brain) {
/* code for freeing the 3D array of structures */ }
I'm running on Ubuntu 14.04 and using Nvidia's NVCC compiler to run the code on GPUs, though this shouldn't be relevant to the error at hand.
You should replace
typedef struct neuron Neuron;
with
typedef struct neuronHead Neuron;
When writing
struct neuronHead { ... } neuron;
you introduce two elements:
a compound data type named "struct neuronHead",
and a variable named "neuron" having type "struct neuronHead".
Typedefs allow to create aliases for data types:
typedef <original_type> <alias_type>;
while in your example an <original_type> (struct neuron) is not a proper type. Proper type definitions are both:
struct neuronHead { ... } neuron; /* data type AND variable were introduced */
typedef struct neuronHead Neuron; /* data type introduced */
and:
typedef struct neuronHead { ... } Neuron; /* data type AND type alias were introduced */
Sample usage of pre-defined types:
struct neuronHead n1; /* correct */
Neuron n2; /* also correct */
struct neuron n3; /* incorrect: 'neuron' is variable name! */
Thank you.
In your code, there is no struct neuron you can typedef to. In your case, neuron is a global variable of type struct neuronHead.
You need to change your code to
struct neuronHead {
int x, y, z;
struct neuronHead *apical[25];
struct neuronHead *basal[25];
struct neuronHead *axon[25];
int time;
};
typedef struct neuronHead Neuron;
or,
typedef struct neuronHead Neuron;
struct neuronHead {
int x, y, z;
Neuron *apical[25];
Neuron *basal[25];
Neuron *axon[25];
int time;
};
or,
typedef struct neuronHead {
int x, y, z;
struct neuronHead *apical[25];
struct neuronHead *basal[25];
struct neuronHead *axon[25];
int time;
} Neuron;
Consider creating an instance of an int:
int some_int;
In C, in general, the syntax is:
<type> <variable_name>
When you have written something like this:
struct Thing {
int i;
/* Other members... */
} thing;
What this actually means is: create a variable, named thing, which is of type struct Thing, and this structure is defined as follows: { int i; /* Other members... */ }.
Then you do something like this:
typedef struct thing SomeThing;
At this point, it makes no sense, as you are trying to typedef an instance (thing).
What you probably meant was something like this:
struct Thing {
int i;
/* Other members... */
}; /* Nothing here! It's the end of type definition. */
typedef struct Thing thing; /* Typedef "struct Thing" -> "thing". */
The general syntax for typedef is:
typedef <original_type> <new_alias>
So it can be made shorter:
typedef /* Typedef the following struct... */
struct Thing {
int i;
/* Other members... */
}
thing; /* ... to such a name. */
Then you can correctly use thing as a variable type.
Also: There are no references in C, just the pointers.

Error in the use of linked-lists in C

The function doesnt work. The rest of the code is okay. It finds the maximum in the lists (its also the last element of the list) and then doesn't quit the iteration, instead of that, the program crashes. I got a hint, that suggests, that I have problems wit the us of "()". Maxhelye means the max_pos
typedef short int shorti;
typedef struct szelveny{
int szsorszam;
int lsorszam;
int het;
shorti talalat;
int tnyeremeny;
}szelveny; //szelveny-->ticket, szsorszam-->ticketnumer, //lsorszam-->lotterynumber,het-->week, tnyeremeny-->prize
typedef struct szelveny_element{
szelveny szelveny;
struct szelveny_element *next;
}szelveny_element,*szelveny_pointer;
typedef struct lottozo{
int lsorszam;
shorti het;
int sszelveny;
int nyeremeny;
} lottozo; //lottozo-->lottery
typedef struct lottozo_element{
lottozo lottozo;
struct lottozo_element *next;
} lottozo_element,*lottozo_pointer;
typedef struct het{
shorti het;
lottozo_pointer lhead;
szelveny_pointer szhead;
} het;
typedef struct het_element{
het het;
struct het_element *next;
}het_element,*het_pointer;
szelveny_pointer szelvenyek=0;
lottozo_pointer lottozok=0;
het_pointer hetek=0;
int maxnyeremenyhelye2(int ahet) //maxprizeposition, ahet-->week got as parameter
{
int max=0,maxhelye=-1;
het_pointer hp;
for(hp=hetek;hp!=0;hp=hp->next)
if(hp->het.het==ahet)
{
lottozo_pointer lp;
for(lp=hp->het.lhead;lp!=0;lp=lp->next)
{
if(lp->lottozo.nyeremeny>=max)
{
max=lp->lottozo.nyeremeny;
maxhelye=lp->lottozo.lsorszam;
}
}
return maxhelye;
}
}
Your function int maxnyeremenyhelye2(int ahet) does not always return a value - didn't your compiler warn you about this? The line
return maxhelye;
should be moved down below the following brace.

Initializing a struct within a union within a struct in C

struct huffnode{
int freq;
union{
struct children
{
struct huffnode * l;
struct huffnode * r;
}
char c;
}un;
};
I'm trying to create a program that implements a huffman tree but in order to do that I need to create nodes with a left and right node pointer in them. The problem is that I don't know how to initialize the struct children. Anyone have any ideas?

access element of struct passed into a void* pointer

I'm working with a binary search tree data structure to sort a series of structs with the type definitions:
typedef struct {
char c;
int index;
} data_t;
typedef struct node node_t;
typedef node {
void *data;
node_t *left;
node_t *right;
}
The node_t typedef is from a library provided to me for this purpose, presumably with a void* pointer to ensure polymorphism. node will be passed into the function:
static void
*recursive_search_tree(node_t *root,
void *key, int cmp(void*,void*))
Within the recursive_search_tree function, I want to be able to modify the code to use the index element as a condition to find the match closest to the index of the linear pass over an array of characters, which would ultimately involve a data_t being passed into *key and key->index being accessed within the function.
The Question
Is it possible to access key->index where key is a void* pointing to a data_t struct, or would this only be possible if data_t was declared as the type for key? I have tried to do the latter, however even casting the pointer to an int doesn't seem to pass the compiler.
Sure it's possible, you'd cast key as type *data_t. (As long as that's really what key points to!)
key /* argument of type void* */
(data_t*)key /* cast as type data_t* */
((data_t*)key)->index /* dereferenced */
Here is a simple example:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
char c;
int index;
} data_t;
typedef struct node {
void *data;
struct node *left;
struct node *right;
} node_t;
static int cmp(void *lhs, void *rhs)
{
return ((data_t *)lhs)->index - ((data_t *)rhs)->index;
}
int main(void)
{
data_t d0;
data_t d1;
d0.c = 'A';
d0.index = 1;
d1.c = 'B';
d1.index = 2;
printf("d0 < d1? %s\n", (cmp((void *)&d0, (void *)&d1) < 0 ? "yes" : "no"));
printf("d1 < d0? %s\n", (cmp((void *)&d1, (void *)&d0) < 0 ? "yes" : "no"));
return EXIT_SUCCESS;
}
This is type unsafe, as is any use of void. The use of void is generally because the intermediate is holding onto something it doesn't use for someone else's convenience.
This is a C function to let you hold whatever you want in a tree.
All it does is return whatever pointer you give it.
In your search function
int cmp(void* dt1, void* dt2)
{
data_t* data1 = (data_t*)dt1;
data_t* data2 = (data_t*)dt2;
/* Do what you need with data1 and data2 here */
}
Should let you do whatever you need. The problem you have is you need to cast your values inside the function. The parameters to cmp should exactly match the API for the library you are using, which says void* for the parameters.

C union and struct question

I have a tree structure. The nodes would have a leaf node type and internal node type, so I defined these structures, so the internal node would be able to point to either internal nodes or leaf nodes. However, I am having trouble in accessing the child pointers, how can I do that, after all does my code make sense at all?
typedef struct leaf_node_t {
int type;
int key;
int *data_ptr[2]; //This will point to real data.
} leaf_node_t;
typedef struct internal_node_t {
int type;
int key;
typedef union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
} node_ptr;
} internal_node_t;
The typedef of node_ptr does not actually add a field to its enclosing struct. The following adds the fields first, and then follows up with the typedef. The other change I made was having the union represent a single pointer, leaving it to the struct that uses it to decide how many pointers it wants.
typedef struct internal_node_t{
int type;
int key;
union node_ptr_t {
struct internal_node_t* iptr;
leaf_node_t* lptr;
} node_ptr[2];
}internal_node_t;
typedef union node_ptr_t node_ptr_t;
Try this:
typedef struct leaf_node_t{
int key;
int *data_ptr[2];//this will point to real data
} leaf_node_t;
struct internal_node_t;
typedef union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
} node_ptr;
typedef struct internal_node_t{
int key;
node_ptr node;
} internal_node_t;
int main()
{
internal_node_t inode;
leaf_node_t* leaf_node = inode.node.lptrs[0];
return 0;
}
Alternately, if you don't actually need to use the union typedef anywhere else:
typedef struct leaf_node_t{
int key;
int *data_ptr[2];//this will point to real data
}leaf_node_t;
typedef struct internal_node_t{
int key;
union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
}node_ptr;
}internal_node_t;
int main()
{
internal_node_t inode;
leaf_node_t* leaf_node = inode.node_ptr.lptrs[0];
return 0;
}
You should add a flag in the internal_node to know what is the node_ptr, if it's an internal_node_t or a leaf_node_t. Probably a int isInternal[2]; (after the key and before the typedef). if it's 0 the it's internal, if it's 1 then it's leaf_node_t. C language doesn't have a typeof or a GetType to know what type of memory is pointed by a pointer (and C++ has it only if you are compiling with the RTTI "option" activated)

Resources