使用cython与C++访问结构中的向量的怪异bug
问题描述:
我正在使用cython与C++编译器,并且出现奇怪的分段错误等。使用cython与C++访问结构中的向量的怪异bug
我的问题可以总结与此代码段:
from libc.stdlib cimport malloc,free
from libcpp.vector cimport vector
from libcpp.string cimport string
cdef struct vstruct:
int a
double b
vector[int] v
cpdef main():
cdef vstruct* vptr
vptr = <vstruct*> malloc(sizeof(vstruct))
vptr[0].v = [1,2]
print vptr[0].v
print vptr[0].v
main()
产生的输出:
[1,2]
[0,0]
因此,什么在这里发生? print语句是否改变了结构体中的向量?我很困惑
答
malloc
分配但不初始化内存。因此,当您尝试指定矢量时,矢量处于未定义状态,并且表现出不可预测性,导致分段错误和不可预知的输出。 (究竟何时以及如何分割发生故障时也不可预知的 - 在我的情况下,它似乎是在Python的关闭这可能表明,分配到矢量改写一些Python内部。)
你需要做的就是分配vptr
什么与C++运算符new
(它会正确初始化所有组件)。您需要更改
cdef struct vstruct:
到
cdef cppclass vstruct:
(这是为了安抚用Cython而不是C++ - 有从它们的默认成员访问的结构和类之间没有真正的区别在C++中分离)。
你再改
vptr = <vstruct*> malloc(sizeof(vstruct))
到
vptr = new vstruct()
,同时与他们的默认构造函数初始化所有组件分配内存。
(您还应该在使用del vptr
时完全免费)
精彩。 我试图做到这一点,但Cython抱怨关键字new。我不知道cppclass关键字。非常感谢你。 那么,何时以及如何使用malloc来分配堆上的内存?用cython C++中的结构来做这件事是否合理? –
malloc只有对于有一个微不足道的构造函数/析构函数的东西才真正确定。你的结构在没有vector的情况下会很好,但是因为vector需要用C++方式管理内存,所以它需要被初始化和销毁。 – DavidW