- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在使用 Cython 的 Python/C++ 代码之间遇到内存所有权问题。我不确定解决此问题的最佳方法是什么。所以我很感激任何帮助。
我的策略如下:
对于 NetInfo 对象,我需要存储指向其他 NetInfo 对象的指针以指示两个对象之间的交互。
我的(相关的)C++代码如下:
struct NetInfoData;
class NetInfo {
public:
NetInfo();
NetInfo(NetInfo const& rhs);
virtual ~NetInfo();
...
std::vector<NetInfo*> getBridgedNets() const;
void addBridgedNet(NetInfo const* ni);
protected:
NetInfoData* data_;
};
struct NetInfoData
{
std::string name;
...
std::vector<NetInfo*> bridged_nets; <-- NOTE: Storing pointers.
};
NetInfo::NetInfo()
: data_(0)
{
std::cout << "Constructor " << this << std::endl;
data_ = new NetInfoData();
}
NetInfo::~NetInfo()
{
std::cout << "Destructor " << this << std::endl;
delete data_;
}
NetInfo::NetInfo(NetInfo const& rhs)
: data_(0)
{
std::cout << "Copy constructor " << this << std::endl;
data_ = new NetInfoData();
data_->name = rhs.data_->name;
...
data_->bridged_nets = rhs.data_->bridged_nets;
}
std::vector<NetInfo*>
NetInfo::getBridgedNets() const
{
return data_->bridged_nets;
}
void
NetInfo::addBridgedNet(NetInfo* n)
{
data_->bridged_nets.push_back(n);
}
我的(相关)Cython 代码如下。它编译/工作正常。
from cython.operator cimport dereference as deref
from libcpp.vector cimport vector
cdef extern from 'NetInfo.h':
cdef cppclass NetInfo:
NetInfo() except +
NetInfo(NetInfo&) except +
...
vector[NetInfo*] getBridgedNets()
void addBridgedNet(NetInfo*)
cdef class PyNetInfo:
cdef NetInfo* thisptr
def __cinit__(self, PyNetInfo ni=None):
if ni is not None:
self.thisptr = new NetInfo(deref(ni.thisptr))
else:
self.thisptr = new NetInfo()
def __dealloc__(self):
del self.thisptr
...
def get_bridged_nets(self):
cdef PyNetInfo r
cdef NetInfo* n
cdef vector[NetInfo*] nets = self.thisptr.getBridgedNets()
result = []
for n in nets:
r = PyNetInfo.__new__(PyNetInfo)
r.thisptr = n
result.append(r)
return result
def add_bridged_net(self, PyNetInfo ni):
self.thisptr.addBridgedNet(ni.thisptr)
现在我的Python伪代码如下:
import PyNetInfo as NetInfo
a = NetInfo() # Create a
Update data members of a # Populate a
tmp = NetInfo(a) # Call copy constructor of a
for n in xrange(5): # a interacts with five other NetInfo objects so create and call them to a via add_bridged_net()
x = NetInfo(tmp) # Call copy constructor to make copy of tmp (not a!!)
Update data members of x
a.add_bridged_net(x) # Store pointer to x in a (a is updated!)
有问题的代码是x = NetInfo(tmp)。在第 2 次迭代 中,分配给 x 的旧内存将被释放,因为 x 现在指向一个新对象。这将导致 a 现在包含一个无效指针。
示例运行:
create a
Constructor 0x101ecd0
create tmp
Copy constructor 0xd71d30
create bridge x
Copy constructor 0xd71bb0
add bridged net:
create bridge x
Copy constructor 0xc9f740
Destructor 0xd71bb0 <--- Destructor on old x is called due to reassignment which causes a to contain an invalid pointer (hence, eventually segfault)
add bridged net:
我不太确定如何管理内存来解决这个问题。谁能帮忙?
我在想也许可以使用共享指针?所以在我的 C++ 代码中,我说
typedef std::shared_ptr<NetInfo> NetInfoShPtr;
然后,
std::vector<NetInfo*> bridged_nets -> std::vector<NetInfoShPtr> bridged_nets;
但是我不确定在 cython 方面该怎么做。这行得通还是有其他(更简单?)的方法?感谢您的任何想法。
最佳答案
我能够使用共享指针解决这个问题(让它完成管理的所有脏工作)。唯一的麻烦是现在需要在 Cython 中到处使用大量 deref(self.thisptr) 来调用 C++ get/set 方法:)。
C++ 变化:
class NetInfo
typedef std::shared_ptr<NetInfo> NetInfoShPtr;
class NetInfo {
public:
NetInfo();
NetInfo(NetInfo const& rhs);
virtual ~NetInfo();
...
std::vector<NetInfoShPtr> getBridgedNets() const;
void addBridgedNet(NetInfoShPtr const& ni);
protected:
NetInfoData* data_;
};
Cython 变化:
from cython.operator cimport dereference as deref
from libcpp.vector cimport vector
from libcpp.memory cimport shared_ptr
cdef extern from 'NetInfo.h':
ctypedef shared_ptr[NetInfo] NetInfoShPtr
cdef cppclass NetInfo:
NetInfo() except +
NetInfo(NetInfo&) except +
...
vector[NetInfoShPtr] getBridgedNets()
void addBridgedNet(NetInfoShPtr&)
cdef class PyNetInfo:
cdef NetInfoShPtr thisptr
def __cinit__(self, PyNetInfo ni=None):
if ni is not None:
self.thisptr = NetInfoShPtr(new NetInfo(deref(ni.thisptr)))
else:
self.thisptr = new NetInfoShPtr(new NetInfo())
def __dealloc__(self):
self.thisptr.reset() # no del, reset the shared pointer
...
def get_bridged_nets(self):
cdef PyNetInfo r
cdef NetInfoShPtr n
cdef vector[NetInfoShPtr] nets = deref(self.thisptr).getBridgedNets() # Must derefence
result = []
for n in nets:
r = PyNetInfo.__new__(PyNetInfo)
r.thisptr = n
result.append(r)
return result
def add_bridged_net(self, PyNetInfo ni):
deref(self.thisptr).addBridgedNet(ni.thisptr) # Must dereference
关于python - Cython:存储指针时 Python/C++ 之间的内存所有权问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37311052/
我正在使用 tcod-rs。用于绘制到 RootConsole 的每个方法都采用一个可变引用。中央循环是一个 while 循环,它等待窗口关闭、清除屏幕、绘制,然后刷新。 “检查窗口关闭”方法也采用可
我写了一个具有这种形式的函数: 结果 f(const IParameter& p); 我的意图是这个签名将明确表明函数没有取得参数 p 的所有权。 问题是 Result 将保留对 IParameter
这个问题在这里已经有了答案: 关闭 9 年前。 Possible Duplicate: What is a smart pointer and when should I use one? 我正在阅
假设我有一个类: class Scheduler { Scheduler(JobService *service); AddJob(JobID id, ISchedule *sched
我试图弄清楚所有权如何与函数 CVMetalTextureGetTexture 一起工作: CVMetalTextureRef textureRef; // ... textureRef is cre
这个问题在这里已经有了答案: Should we pass a shared_ptr by reference or by value? (10 个答案) 关闭 4 年前。 例如 class A {
我正在做一个附带项目,我需要根据他的 gmail 帐户或任何其他参数来验证 channel 是否属于某个用户……这基本上是为了避免假帐户。是否可以? 最佳答案 是的, 跟随 youtube 记录的链接
我在使用Core Foundation Array时发现了一个奇怪的问题!这是代码片段 fname = CFStringCreateWithFormat(kCFAllocatorDefault, NU
有没有一种方法可以设置在 apache 下运行的 php 来创建文件夹,该文件夹的文件夹属于创建它的程序的所有者,而不是由 apache 拥有? 使用 word press 它会创建要上传到的新文件夹
我编写了以下函数来使用 boost.date_time 获取日期/时间字符串. namespace bpt = boost::posix_time; string get_date_time_stri
我在使用 Docker 容器时遇到了一个有点烦人的问题(我在 Ubuntu 上,所以没有像 VMWare 或 b2d 这样的虚拟化)。我已经构建了我的镜像,并且有一个正在运行的容器,它有一个来 sel
根据大多数示例,逻辑上最少有 3 个组织 ( org1, org2, orderer )。 实际上只有 2 个物理组织 ( org1, org2 )。任一组织或约定的第 3 方必须移交订购者组织的职责
我开始学习 Rust,在进行实验时,我发现所有权如何应用于我不理解的元组和数组的方式有所不同。基本上,以下代码显示了差异: #![allow(unused_variables)] struct Inn
我们有一个应用程序,其表单上有许多组件(面板、选项卡、编辑、组合框等)。但根据用户配置文件,其中大多数可以自动填充和/或不可见。因此,用户可以更快地完成工作。 问题:是否有更简单的方法可以在运行时创建
我有以下代码片段: fn f u32>(c: T) { println!("Hello {}", c()); } fn main() { let mut x = 32; let
我想执行示例中的代码: require_once 'google-api-php-client/vendor/autoload.php'; $client = new Google_C
这个问题在这里已经有了答案: What is move semantics? (11 个答案) 关闭 3 年前。 我有一个看起来像这样的构造函数: Thing::Thing(std::vector
我们正在使用服务帐户从服务器上传文件,但它已达到其存储配额限制。所有文件都已添加到另一个用户(具有 100 Gb 存储配额的 @gmail.com 帐户)创建的文件夹下,但上传的所有文件均归该服务帐户
我正处于 this question 中描述的 sme 情况。 .那个提问者找到的解决方案是 Full access !== Owner. I need to read the documentati
我正处于 this question 中描述的 sme 情况。 .那个提问者找到的解决方案是 Full access !== Owner. I need to read the documentati
我是一名优秀的程序员,十分优秀!