C - Loading a Struct Containing a Pointer to a Pointer - c

This produces an incompatibility warning:
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
int key;
int data;
struct htData_* next;
struct htData_* prev;
}htData_;
typedef struct
{
int num_entries;
struct htData_** entries;
}ht_;
ht_* new_ht(int num_entries);
int ht_add(ht_* ht_p, int key, int data);
int main()
{
int num_entries = 20;
//crate a hash table and corresponding reference
ht_* ht_p = new_ht(num_entries);
//add data to the hash table
int key = 1305;
ht_add(ht_p,key%num_entries,20);
return 0;
}
ht_* new_ht(int num_entries)
{
ht_ *ht_p;
ht_ ht;
ht.num_entries = num_entries;
ht_p = &ht;
//create an array of htData
htData_ *htDataArray;
htDataArray = (htData_*) malloc(num_entries * sizeof(htData_));
//point to the pointer that points to the first element in the array
ht.entries = &htDataArray; // WARNING HERE!!!!!!!!!!!!!!!!
return ht_p;
}
I'm trying to copy the **ptr to the struct containing a **ptr.
Update: My simplified code was not accurate so I've posted the actual code.

The problem is that struct htData_ and htData_ are not the same thing! As far as the compiler is concerned, struct htData_ doesn't exist—it's an incomplete type. htData_, on the other hand, is a typedef for an anonymous structure. For a more detailed analysis, see Difference between struct and typedef struct in C++.
So, you're getting a warning because ht.entries is declared as the type struct htData_**, but the right-hand side of that assignment has type <anonymous struct>**. To fix this, you need to define struct htData_:
typedef struct htData_
{
...
} htData_;

This line is not proper:
htData_ array[20] = htDataArray;
You cannot assign a pointer to an array.
In your edited code, here is the problematic line:
//point to the pointer that points to the first element in the array
ht.entries = &htDataArray;
Actually, syntactically it's correct, so it should not give warning. But you are doing wrong stuff here. If you want ht.entries pointing to the first element of array than you need to declare it as,
htData_* entries; // 'struct' keyword not needed ahead of declaration
and assign it as,
ht.entries = &htDataArray[0];

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.

pointers between dynamic structs memory

I am trying to solve a little problem from my university, but i get into trouble completing it.
The task is to write a code defining all the data structures and create a link between them using pointers and mallocs.
ASSIGNMENT :
There are 3 blocks.
1) is a static block with 2 fields, 1st field is an integer, and a second field points to another block.
2) a block with 2 fields. 1st field points to the first block and 2nd field points to the 3rd block.
3) a block with 2 fields. 1st field is an integer and 2nd field points to the first block.
I have started creating the code and making the links but i keep getting errors which i cant seem to find thier logic.
struct A;
struct B;
struct C;
typedef struct {
int element;
struct A * pointer3;
}C;
typedef struct {
struct A * pointer 1;
struct C * pointer 2;
}B;
typedef struct {
int element;
struct B * pointer 0;
}A;
int main (){
A a;
a.pointer0 = (B*)malloc(sizeof(B));
I have reached farther then that, but the problem i get is in the last line.
Gives me the error warning: assignment from incompatible pointer type
Question: What does struct A look like? Answer: Your compiler has no idea because you never defined it.
You're assuming forward-declaring a structure type, then formally declaring a typedef alias to a structure where the alias name (but not tag) is the same as the structure tag (with no name) will resolve. It won't. You have to do that yourself.
Start with simple. Get rid of the type aliases entirely. And get rid of any unnecessary forward decls as well (B and C) What would it look like?
#include <stdio.h>
#include <stdlib.h>
struct A; // fwd decl
struct C
{
int element;
struct A *pointer3; // uses fwd decl
};
struct B
{
struct A *pointer1; // uses fwd decl
struct C *pointer2; // uses prior def
};
struct A // resolves fwd decl
{
int element;
struct B *pointer0; // uses prior def
};
int main()
{
struct A a;
a.pointer0 = malloc(sizeof(struct B));
}
That works (in the most optimistic definition of the term). If you want to use typedef aliases, you can add them in now. For example, here is all three structures both tagged and aliased.
#include <stdio.h>
#include <stdlib.h>
struct A;
typedef struct A A;
typedef struct C
{
int element;
A *pointer3;
} C;
typedef struct B
{
A *pointer1;
C *pointer2;
} B;
struct A
{
int element;
B *pointer0;
};
int main()
{
A a;
a.pointer0 = malloc(sizeof(B));
}

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;

Array of Pointers dereferencing when accessed in C

I have a array structure that should hold a pointer to another structure. My structures are like this:
struct Term{
char* term;
int times;
};
typedef struct Term TERM;
struct HeapTer{
TERM* Term;
size_t used;
size_t size;
};
typedef struct HeapTer HEAPTER;
struct Pack{
HEAPCON* hCon;
HEAPTER* hTer;
};
typedef struct Pack PACK;
Pack will just hold the pointers of both arrays I will return from my structure loading function.
My problem is when I will call a function, where I will insert a given term to the consults term heap.
InsertHeapTer(pack->hTer->Term[ind_term],consult->hTer)
Where InsertHeapTer is defined as InsertHeapTer(TERM* Ter, HEAPTER *t).
The compiler gives me the following error, error: incompatible types when assigning to type 'TERM {aka struct Term}' from type 'TERM * {aka struct Term *}'.
So, it is saying that when I use pack->hTer->Term[ind_term] it gives me a TERMand not a TERM*, even though it is defined as a pointer in the structure.
What am I doing wrong and why is this happening?
EDIT:
Code to reproduce:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Termo{
char* termo;
int vezes;
};
typedef struct Termo TERMO;
struct HeapTer{
TERMO* Termo;
size_t usado;
size_t tam;
};
typedef struct HeapTer HEAPTER;
struct consulta{
char *Local;
HEAPTER *hTer;
};
typedef struct consulta CONSULTA;
struct HeapCon{
CONSULTA* con;
size_t usado;
size_t tam;
};
typedef struct HeapCon HEAPCON;
struct Pacote{
HEAPCON* hCon;
HEAPTER* hTer;
};
typedef struct Pacote PACOTE;
void InsereHeapTer(TERMO* Ter, HEAPTER *t){
}
int main(){
PACOTE* pack;
CONSULTA* consulta;
int ind_termo=1;
InsereHeapTer(pack->hTer->Termo[ind_termo],consulta->hTer);
return 0;
}
void InsereHeapTer(TERMO* Ter, HEAPTER *t){
}
I'm sorry, but this was the minimal setup I could do.
So, it is saying that when I use pack->hTer->Term[ind_term] it gives
me a TERM and not a TERM*,
Yes.
even though it is defined as a pointer in
the structure.
Be careful: even though what is defined as a pointer? It is pack->hTer->Term that is so defined. With that being the case, then, pack->hTer->Term[ind_term] indeed has type TERM. It is equivalent to *(pack->hTer->Term + ind_term).
And that suggests a resolution: if you meant to pass a pointer to that item instead of a copy of the item, then you can use pointer arithmetic to produce the wanted pointer as pack->hTer->Term + ind_term. I tend to prefer the simplicity of that, but stylistically, I'm sure some people would prefer the equivalent expression &pack->hTer->Term[ind_term].
To simplify the offending line of code, you can do:
TERMO* termo = pack->hTer->Termo;
InsereHeapTer(termo[ind_termo],consulta->hTer);
Clearly, termo is a TERMO*. The [] operator is defined like this:
The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).
C.11 §6.5.2.1 ¶2
Thus, your function call is equivalent to:
InsereHeapTer(*(termo + ind_termo),consulta->hTer);
And this can be simplified again:
TERMO* termo_plus_ind = termo + ind_termo;
InsereHeapTer(*termo_plus_ind,consulta->hTer);
When you dereference a TERMO*, you get a TERMO.

how to access a struct within a list within a struct with a pointer?

I'm given a number i, and a pointer which points to a struct which contains a list of structs, basically what I want to do is go over all of the lists and look which struct in it has the number i.
typedef struct struct1 { int num; } struct1;
typedef struct struct2 {
struct1 somestruct1;
struct2 *pnext;
} struct2;
struct struct3 {
struct2 somestruct2;
};
I'm new to coding and I can't seem to figure this out, here's how I'm trying to access a num field in some struct1 given a pointer to struct3
struct3 temp->somestruct2.somestruct1.num ;
It seems that your confusion might be due to whether to use a "." or a "->"
Here is a general rule...
If the item to the left is a pointer, use "->". If it is not a pointer, use ".".
If "temp" is defined "struct struct3 temp", then temp is not a pointer. Hence, it should be followed by a "." to access the sub-element(s) of temp.
The temp sub-element "somestruct1" is also not defined as a pointer in struct2; hence, to access the sub-element(s) of somestruct1, it should be followed by a ".".
temp.somestruct2.somestruct1.num
Here is an example of how that can be done.
#include <stdlib.h>
#include <stdio.h>
typedef struct struct1 { int num; } struct1;
typedef struct struct2 {
struct1 somestruct1;
struct struct2 *pnext;
} struct2;
struct struct3 {
struct2 somestruct2;
};
int main()
{
struct struct3* s = malloc(sizeof(struct struct3));
s->somestruct2.somestruct1.num = 1;
printf("%d\n", s->somestruct2.somestruct1.num);
free(s);
}
Whenever you have a pointer, you must dereference it before you can use the thing it points to. The dereference operator is unary * and then . to access the structs members.
So long hand you could write
(*s).somestruct2.somestruct1.num = 1;
This is a very common operation and its also quite ugly, so an operator that combines them is ->, hence
s->somestruct2.somestruct1.num = 1;
struct3 s3;
int num = s3.somestruct2.somestruct1.num;
or
struct3 *s3;
int num = s3->somestruct2.somestruct1.num;

Resources