1

I try to understand what value we get when dereference the pointer to struct.

My struct is.

    struct car
{
    int a = 5;
    int b = 10;
    int c = 2;
    int d = 14;
    int e = 20;
};

My code in main function is

int main()
{
    car  k1,k2,k3,k4,k5; // declare struct variable
    car* ptr1,*ptr2,*ptr3,*ptr4,*ptr5;// declare pointer to struct variable
    ptr1 = &k1;
    ptr2 = &k2;
    ptr3 = &k3;
    ptr4 = &k4;
    ptr5 = &k5;

    printf("*ptr1=%d *ptr2=%d *ptr3=%d *ptr4=%d *ptr5=%d  \n", *ptr1,*ptr2,*ptr3,*ptr4,*ptr5);
 };

When I dereference ptr1 to ptr5.I get the value correspond with the value of member in struct(value a to e).Why I get this value.

Kelee
  • 53
  • 5
  • 9
    This is not C code. C does not allow struct field initialisers like that. Perhaps you are coding in C++. If so, please update the tags. – kaylum Oct 03 '20 at 07:19
  • Can you clarify write what your program outputs, and what do you expect it to output. – Luka Rahne Oct 03 '20 at 07:24
  • 4
    `When I dereference ptr1 to ptr5` When you do that you are passing `struct car` values to `printf` which expects `int` values because of the `%d`'s. That is UB (undefined behavior) right there. – dxiv Oct 03 '20 at 07:24
  • The compiler should have warned you about the undefined behavior. Otherwise try turning on `-Wall`. – user202729 Oct 03 '20 at 07:25
  • 2
    You are confusing C struct and C++ struct. In C, the address of a struct is the address of the first member. So you can print the first integer member by dereferencing the struct. (which explains your use of `printf` and the `"%d"` conversion specifier) In C++, the struct and class are identical to each other, but are not guaranteed the same as a C struct from an address of the first member standpoint. See [First member of class](https://stackoverflow.com/questions/25377877/first-member-of-class) – David C. Rankin Oct 03 '20 at 07:31
  • 2
    You are also using `printf` to get around `error: no match for ‘operator<<’` if you attempt the output with `std::cout`, but you invoke *Undefined Behavior* with `printf` because of the type mismatch between `*ptr1`, etc.. and `"%d"`. You can mask that by casting the pointer to `int*`, e.g. `*(int*)ptr1` -- but if you ever have to cast around an error - all hope is lost anyway.... This looks a lot like an *XY Problem*. See: [What is the XY problem?](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) -- what do you need to accomplish? – David C. Rankin Oct 03 '20 at 07:49

2 Answers2

0

To be able to print struct you need to overload operator <<. Your struct then should look like this:

struct car
{
    int a = 5;
    int b = 10;
    int c = 2;
    int d = 14;
    int e = 20;

    friend std::ostream& operator<<(std::ostream& os, const car& c) {
      os << "Struct data:\n";
      os << "------------\n";
      os << "a var: " + std::to_string(c.a) + "\n";
      os << "b var: " + std::to_string(c.b) + "\n";
      os << "c var: " + std::to_string(c.b) + "\n";
      os << "d var: " + std::to_string(c.b) + "\n";
      os << "e var: " + std::to_string(c.b) + "\n";
      return os;
    }
};

Then if you would print dereferenced ptr like this:

std::cout << *ptr1 << std::endl;

You will see output like this:

Struct data:
------------
a var: 5
b var: 10
c var: 10
d var: 10
e var: 10

You can return what you want, depends on you.

gawron103
  • 167
  • 6
  • 21
0

Variadic functions do not have type checking and practically may pun types. Essentially you passed content of structure as raw values and format string described how to treat them. Luckily, in this case struct has no padding, so first five integers were read accordingly. The behaviour in this case is unspecified and depends on implementation of compiler and ABI.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42