get value from array pointer to pointer of a struct - c

Im expecting to get the value of the pointer that pp is pointing to
this is my struct
struct game
{
int rank;
int year;
char *name;
char *platform;
char *genre;
char *publisher;
// sales below represented in millions
float NA_sales;
float EU_sales;
float JP_sales;
float other_sales;
float global_sales;
} Game;
i got the array of pointer to pointer as
struct Game **arr[MAX_NUM]; // max num is 100
and i assign
arr[counter] = &new_game; // new_game is calloc as struct game *new_game = calloc(1, sizeof(struct game));
i tried with
arr[counter]->publisher
but it return as
'*arr[counter]' is a pointer; did you mean to use '->'?
printf("%s", arr[counter]->new_game->publisher);

So the error here is that you have an extra level of indirection that the compiler isn't expecting which gives you an error with a bad suggestion. Since you have a pointer to pointer to array, the type of arr[counter] is still a pointer to pointer to struct. Here is how you access struct member via a pointer (as you know):
struct Foo* bar;
bar->a = 0;
But if that was a pointer to pointer, we need to dereference the first pointer to be able to use -> correctly:
struct Foo** bar;
(*bar)->a = 0;
Another way to look at it is bar->a is nothing more than syntax sugar for (*bar).a. You have an extra level of indirection, so without the ->, you would need (**bar).a.

I do not know why you want to have so many levels of indirection.
To access using pointer
typedef struct game
{
int rank;
int year;
char *name;
char *platform;
char *genre;
char *publisher;
// sales below represented in millions
float NA_sales;
float EU_sales;
float JP_sales;
float other_sales;
float global_sales;
} Game;
/* ..... */
/* how to access */
int main(void) {
Game **arr[100];
Game *newGame = calloc(1, sizeof(*newGame));
arr[0] = &newGame;
printf("%f", arr[0][0] -> NA_sales);
printf("%f", (*arr[0]) -> NA_sales);
printf("%f", (**arr) -> NA_sales);

Related

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, assignment of struct pointers changes the content of the right side of assignment

I have the following structs:
typedef struct{
char *name;
int size;
void *data;
} Struct1;
typedef struct st2{
char *name;
struct st2 **Struct2array;
Struct1 **Struct1array;
int Struct1_n;
int Struct2_n;
} Struct2;
where the double pointers in Struct2 are used as dynamic arrays of pointers to other Struct2's or Struct1's. The data in Struct1 is used as a dynamic array to store some data. Struct1_n and Struct2_n represent the number of elements inside of their respective dynamic arrays.
When I make a variable of type Struct1, I fill the data by casting a char * to a void * and using memcpy to copy it into data. If I then cast to data back into a char pointer, I can get back the contents and they are generally the same. However, for some reason the values that data in Struct1 is pointing to change after the following line:
struct2pointer->Struct1array[struct2pointer->Struct1_n - 1] = struct1pointer;
Examples:
printf("%d\n", *(char *)(struct1pointer->data));
gives the value of the 1stbyte of struct1pointer->data as -96 immediately after the problematic line regardless of the value it printed immediately before(which was the same one memcpy-d into data). if I add 1 to the pointer before casting it to a char pointer(2nd byte) it always gives 32, if I add 2 (3rd byte)it always gives 96 and so on.
Why is this happening when the struct1pointer is on the right side of the assignment operator and what can be done to fix this?
EDIT:
Functions where content changes:
void struct2_addstruct1(Struct2 struct2pointer, Struct1 *struct1pointer){
struct2->Struct1_n++;
struct2pointer->Struct1array = realloc(struct2pointer->Struct1array, struct2->Struct1_n * sizeof(Struct1 *)); //edited to remove increment that was added on accident, isn't in the original code
struct2pointer->Struct1array[struct2pointer->Struct1_n - 1] = struct1pointer;
}
The function that creates Struct1:
void struct1_init(Struct1 *s, char *name, void *data, int size){
s->name = malloc(strlen(name) + 1);
strcpy(s->name, name);
s->size = size;
s->data = malloc(size);
memcpy(s->data, data, size);
}
This is how that funcion is called when creating struct1:
Struct1 *s;
struct1_init(s, name, data, size);
name, data and size are provided form the outside but shouldn't have anything to do with the problem.
Look at this code:
Struct1 *s;
struct1_init(s, name, data, size);
Here s is uninitialized.
However in struct1_init function you do assume that the pointer s is already pointing to a Struct1.
Maybe you forgot a malloc - like:
Struct1 *s = malloc(sizeof *s);
struct1_init(s, name, data, size);

Is it possible to get the size of the item the pointer is pointing at?

Is it possible to find the size of item_t through the pointer?
typedef struct item
{
char x;
char y;
char life;
}item_t;
void main (void)
{
item_t test;
void *ptr = &test;
printf("%d\n",sizeof(ptr));
}
return: 8
Not if ptr is of type void* -- but it probably shouldn't be.
You can't dereference a void* pointer. You can convert it to some other pointer type and dereference the result of the conversion. That can sometimes be useful, but more often you should just define the pointer with the correct type in the first place.
If you want a pointer to an item_t object, use an item_t* pointer:
item_t test;
item_t *ptr = &test;
printf("%zu\n", sizeof(*ptr));
This will give you the size of a single item_t object, because that's the type that ptr points to. If ptr is uninitialized, or is a null pointer, you'll get the same result, because the operand of sizeof is not evaluated (with one exception that doesn't apply here). If ptr was initialized to point to the initial element of an array of item_t objects:
ptr = malloc(42 * sizeof *ptr);
sizeof *ptr will still only give you the size of one of them.
The sizeof operator is (usually) evaluated at compile time. It uses only information that's available to the compiler. No run-time calculation is performed. (The exception is an operand whose type is a variable-length array.)
The correct format for printing a value of type size_t (such as the result of sizeof) is %zu, not %d.
And void main(void) should be int main(void) (unless you have a very good reason to use a non-standard definition -- which you almost certainly don't). If a book told you to define main with a return type of void, get a better book; its author doesn't know C very well.
Short answer: no. Given only ptr, all you have is an address (answer by WhozCraig).
Longer answer: you can implement inheritance by having the first field in all your structs specify its size. For example:
struct something_that_has_size
{
size_t size;
};
struct item
{
size_t size;
char x;
char y;
char life;
};
struct item2
{
size_t size;
char x;
char y;
char z;
char life;
};
// Somewhere in your code
...
struct item *i1 = malloc(sizeof(struct item));
i1->size = sizeof(struct item); // you are telling yourself what the size is
struct item2 *i2 = malloc(sizeof(struct item2));
i2->size = sizeof(struct item2);
// Later in your code
void *ptr = ... // get a pointer somehow
size_t size = ((struct something_that_has_size*)ptr)->size; // here is your size
But instead of size, you should better record the type of your struct - it's more useful than just the size. This technique is called discriminated union.
You can only cast a void pointer to get what is behind in the correct type, you cannot dereference it directly.
#include <stdio.h>
#include <stdlib.h>
typedef struct item {
char x;
char y;
char life;
} item_t;
int main()
{
item_t test;
void *ptr = &test;
printf("%zu %zu\n", sizeof(*(item_t *) ptr), sizeof(item_t));
exit(EXIT_SUCCESS);;
}
But that is of not much use because you need to know the type in the first place and have won nothing.
TL;DR: no, not possible

dynamically allocating an int array inside a structure

I'm trying to dynamically create an array of ints for grades that are inside of a structure but I have a small syntax error. Here is my code:
typedef struct
{
int Stud_ID;
int class_ID;
int* Grades;
int Grade_Cap;
int Count;
float Average;
}enrollment;
typedef struct
{
int Enrollment_Count;
int Enrollment_Cap;
enrollment *enrollment_list;
}enrollments;
void add_grade_space(enrollments *enroll)
{
enroll->enrollment_list[enroll->Enrollment_Count].Grade_Cap = malloc(sizeof(int)*2);
}
The error I get says: assignment makes integer from pointer without cast.
enroll->enrollment_list[enroll->Enrollment_Count].Grade_Cap = malloc(sizeof(int)*2);
You are trying to allocate memory to Grade_Cap which is not a pointer . It is an integer variable .You need to declare it as int * to allocate memory if you want to.

Is this use of struct pointers correct?

I have this struct:
typedef struct Grades {
int grade1;
int grade2;
int grade3;
int grade4;
int grade5;
}
I created a pointer to a Grades struct using
struct Grades *pointer;
and I have a function() that returns a (void *) pointer to a specific Grades struct.
How do I set my pointer to that specific struct using the (void *) pointer?
I was thinking:
pointer = &function();
but that gives me an error: "'&' requires l-value
Any ideas? And by the way, I can't modify the function so...
If function() returns a pointer, you should be able to just do
pointer = function();
pointer = function();
If function() is returning a void pointer, you don't need to take the address of it, it's already a pointer pointing to a Grades struct.

Resources