I can access the char value of the nested struct, but the int one it shows memory address only, how I can dereference the pointer value of an int one ? here is a sample code:
struct Student {
char firstname[10];
char lastname[10];
struct Class *class;
};
struct Class {
char name[10];
int cap;
};
void printStudents(struct Student *student) {
struct Class *class;
class = student->class;
printf("Capacity => %d\n", &class->cap);
printf("Class => %s\n", &class->name);
}
int main(void) {
struct Student student = {"Ian", "saeidi", {"rust", 24}};
printStudents(&student);
return 0;
}
Output:
Capacity => 34938800
Class => rust
Expected Output:
Capacity => 24
Class => rust
CodePudding user response:
You have several problems:
- You're not allocating any space for
class
, so trying to initialize it with{"rust", 24}
is incorrect. - Even if that was ok,
name
is a singlechar
and cannot hold nor point to a string. - Since the initialization is wrong,
class = student->class;
assignsclass
to invalid memory, and dereferencing it (class->
) invokes undefined behavior. "%d"
printf
format specifier expects anint
, but you pass it anint*
"%s"
printf
format specifier expect achar*
, but you pass it achar (*)[10]
(pointer to a 10 sizechar
array).
One possible fix:
// flip the order of the structs so you can declare a `struct Class class` in
// `struct Student` (no pointer)
struct Class {
// change this from a pointer to array
char name[10];
int cap;
};
struct Student {
char firstname[10];
char lastname[10];
struct Class class;
};
void printStudents(struct Student *student) {
// get a pointer to the address of student->class if you want
struct Class *class;
class = &(student->class);
// now things print appropriately
// pass an `int` to %d
printf("Capacity => %d\n", class->cap);
// pass a `char*` to %s. `class->name` in this context "decays" to a
// pointer to its first element, a `char`
printf("Class => %s\n", class->name);
}
int main(void) {
// now your initialization is valid
struct Student student = {"Ian", "saeidi", {"rust", 24}};
printStudents(&student);
return 0;
}
You could also use dynamic memory allocation instead of arrays.
CodePudding user response:
struct Student student = {"Ian", "saeidi", {"rust", 24}};
is incorrect. The {"rust", 24}
part needs to be changed to a pointer to a struct Class
. That struct Class
could be stored as a variable like this:
struct Class class = {"rust", 24};
struct Student student = {"Ian", "saeidi", &class};
Alternatively, that struct Class
could be stored as a compound literal like this:
struct Student student = {"Ian", "saeidi", &(struct Class){"rust", 24}};
A compound literal behaves rather like an initialized variable, but is anonymous.
The printStudents
function is passing the wrong arguments to printf()
. It is passing the address of class->cap
instead of the value of class->cap
. And it is also passing the address of class->name
instead of the the address of class->name[0]
. That can be corrected by removing the &
from both calls to printf
:
printf("Capacity => %d\n", class->cap);
printf("Class => %s\n", class->name);
N.B. class->name
is the same value as &class->name[0]
.
CodePudding user response:
printf("Capacity => %d\n", &class->cap);
You need to pass printf an integer. &class->cap
is an int *
. So you need to do class->cap
, as you asked for printf to print via "%d".
The same, class->name
is enough, however, this works, as &class->name
is rewritten as class->name
because it's array.
There are other problems, {"rust", 24}
is not a valid initializer for a field of type struct Class *
, but for a struct Class
.