Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strange phenomenon about C++ memory address

That is just crazy!
In order to figure out how objects store in memory in C++,
I write the following code to see the address of variables.
But things get more confused.
So in the following I wonder

why 1 is different from 2 ------does this means that it's a pointer? but why?
why 1 is different from 3 ------it's passed by reference, they should be same?!

#include <iostream>
#include <vector>
using namespace std;

class A {
 public:
  A(int age, string name) : age_(age), name_(name){};
  void SetAge(int age) {
      age_ = age;
  }
  
  int age_;
  string name_;
};

void insert(vector<A>& p) {//passed by reference
    A a1{1, "tom"};
    printf(" p: %p\n", p); // p: 0x7ffc6cc98080 ------------3
    printf("&p: %p\n", &p);//&p: 0x7ffc6cc981a0 ------------4

    printf("&a1: %p\n", &a1); // &a1: 0x7ffc6cc980c0 /on stack, that's no problem

    p.push_back(a1);

    printf("&p[0]: %p\n", &p[0]); // &p[0]: 0x55b54cdd02c0 /on heap, that's no problem
}

int main()
{
    vector<A> persons;
    printf(" persons: %p\n", persons); // persons: 0x7ffc6cc981c0 ------------1
    printf("&persons: %p\n", &persons);//&persons: 0x7ffc6cc981a0 ------------2

    insert(persons);

    printf("&p[0]: %p\n", &persons[0]);// &p[0]:  0x55b54cdd0350
    printf("persons: %p\n", persons); // persons: 0x7ffc6cc981c0 /same as above
    cout << persons.size() << endl; //1
    
}

edit: I'm so sorry for that, the difference between 5 and 6 is not true, I delete a push_back accidentally, I felt so sorry for you, hope that didn't confused you much.

like image 361
G FL Avatar asked Dec 30 '22 18:12

G FL


1 Answers

The format specifier %p requires that the argument is of type void*. If you pass an argument of wrong type, then the behaviour of the program is undefined.

printf(" persons: %p\n", persons);

Here, you pass an argument of type vector<A>, therefore the behaviour of the program is undefined.

Since The argument isn't even a pointer, there is no hope of meaningful output.

printf(" persons: %p\n", &persons);

Here, you pass an argument of type vector<A>*, therefore the behaviour of the program is undefined.

In this case the argument is at least a pointer. On a systems where all pointers have the same representation, the output might be meaningful and represent the address where the pointed object is stored. However, this still violates the precondition of the argument type and the behaviour should not be relied upon.


Conclusions:

  • Don't use wrong types with printf or else the behaviour will be undefined. Study the documentation carefully.
  • There are no correct format specifiers for any class types.
  • Don't use printf. It is difficult to use correctly and there are easier alternatives.
like image 173
eerorika Avatar answered Jan 12 '23 15:01

eerorika