Home > Enterprise >  Access the int value of the nested struct in C
Access the int value of the nested struct in C

Time:04-14

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:

  1. You're not allocating any space for class, so trying to initialize it with {"rust", 24} is incorrect.
  2. Even if that was ok, name is a single char and cannot hold nor point to a string.
  3. Since the initialization is wrong, class = student->class; assigns class to invalid memory, and dereferencing it (class->) invokes undefined behavior.
  4. "%d" printf format specifier expects an int, but you pass it an int*
  5. "%s" printf format specifier expect a char*, but you pass it a char (*)[10] (pointer to a 10 size char 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.

Demonstration

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.

  •  Tags:  
  • c
  • Related