2

I am trying to print the memory address of the same object in both c++ and python with pybind11, but I found the returned memory address from both are not identical.

c++ side

class Example {
  public:
    Example() {std::cout << "constuctor" << this << std::endl;}
    ~Example() {std::cout << "destructor " << this << std::endl;}
};

class ABC {
  public:
    static std::unique_ptr<Example> get_example() {
      // std::shared_ptr<Example> ptr = std::make_shared<Example>();
      std::unique_ptr<Example> ptr = std::make_unique<Example>();
      return ptr;
    }
};

void init_example(py::module & m) {
    py::class_<ABC>(m, "ABC")
    .def_static("get_example", &ABC::get_example);
}

python side

example = my_module.ABC.get_example()
print (example)

the output

constuctor0x234cd80
<Example object at 0x7f5493c37928>
destructor 0x234cd80

the memory address from c++ is 0x234cd80, but python is 0x7f5493c37928

any idea?

4
  • 3
    I don't quite get what you're attempting to print out. You are printing out this in the C++ code, but in actually in get_example, you're creating a std::unique_ptr, and its address is not going to be the same as this. See this example. Issue seems to have nothing to do with Python. Commented May 8, 2019 at 3:20
  • my mistake. I thought the address of std::unique_ptr is the same as the address of the object it points to. Commented May 8, 2019 at 3:57
  • But how to print out the memory address o the object in python? Commented May 8, 2019 at 3:58
  • You need to call the get() function, by whatever means Python gives you. Commented May 8, 2019 at 4:24

2 Answers 2

3

pybind11 creates a Python object which has a reference to C++ object. So addresses of Python pybind11 wrapper and C++ object are different.

The address in default pybind11 str object representation is the address of python object, not of underlying C++ object or it's smart pointer.

If you need to know address of C++ object add a method to you binding code as @PaulMcKenzie suggested.

C++:

namespace py = pybind11;

PYBIND11_MODULE(example_module, m){
  m.def("add", add);

  py::class_<Example>(m,"Foo")
      .def(py::init())
      .def("get_raw_address",[](Example& foo){ return reinterpret_cast<uint64_t>(&foo);});

}

Python:

example = Example()
print(example)
print("C++ address: %x" % example.get_raw_address())

Output:

constuctor 0x10eff20
<example_module.Foo object at 0x7f51c71d4298>
C++ address: 10eff20
destructor 0x10eff20
Sign up to request clarification or add additional context in comments.

Comments

1

I am not familiar with the Python aspect of this question, but focusing on the C++ portion, you are not printing out the correct information.

The std::unique_ptr has a different address than the Example instance that is created, thus the values will be different. If you want to print the address of the item that the unique_ptr is addressing, you need to call the get() function.

Here is a full example showing the differences:

#include <memory>
#include <iostream>

class Example {
  public:
    Example() {std::cout << "constuctor " << this << std::endl;}
    ~Example() {std::cout << "destructor " << this << std::endl;}
};

class ABC {
  public:
    static std::unique_ptr<Example> get_example() 
    {
      std::unique_ptr<Example> ptr = std::make_unique<Example>();
      return ptr;
    }
};

int main()
{
    std::unique_ptr<Example> p = ABC::get_example();
    std::cout << "The unique_ptr address is: " << &p << std::endl;
    std::cout << "The get() function returns: " << p.get() << std::endl;
}

Output:

constuctor 0x555a68bd7c20
The unique_ptr address is: 0x7ffd9fa6c120
The get() function returns: 0x555a68bd7c20
destructor 0x555a68bd7c20

So you need to adjust your Python code to print the return value of get().

2 Comments

I made some changes but the returned memory addresses are still not identical. unique_ptr_address=0x7ffcc78cda70, python_side_address= 0x7ff4c80ab8f0
"So you need to adjust your Python code to print the return value of get()." Or adjust the C++ code, rather?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.