简体   繁体   中英

the memory address of object between python and c++ are not identical

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?

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() .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM