C++;还是Cython内存泄漏? 我正在使用Cython编写的Python扩展模块,它封装了我编写的C++类。

C++;还是Cython内存泄漏? 我正在使用Cython编写的Python扩展模块,它封装了我编写的C++类。,c++,python,memory-leaks,valgrind,cython,C++,Python,Memory Leaks,Valgrind,Cython,崩溃 我有一个简单的python代码,可以导入这个python模块并用它处理一些数据。现在,大约4次中有1次,在模块调用之后,程序在终止之前发生故障。这也意味着所有数据都得到了正确处理。它是这样的: /Users/axe/anaconda/bin/python.app: line 2: 73168 Segmentation fault: 11 使用gdb调试,运行gdbpython,然后运行runcode.py,我得到 Program received signal EXC_BAD_ACCES

崩溃

我有一个简单的python代码,可以导入这个python模块并用它处理一些数据。现在,大约4次中有1次,在模块调用之后,程序在终止之前发生故障。这也意味着所有数据都得到了正确处理。它是这样的:

/Users/axe/anaconda/bin/python.app: line 2: 73168 Segmentation fault: 11
使用gdb调试,运行
gdbpython
,然后运行
runcode.py
,我得到

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: 13 at address: 0x0000000000000000
0x00000001000894ae in PyObject_ClearWeakRefs ()
backtrace
的输出为

#0  0x00000001000894ae in PyObject_ClearWeakRefs ()
#1  0x00000001010edae4 in array_dealloc ()
#2  0x000000010007503e in tupledealloc ()
#3  0x00000001000559b7 in insertdict_by_entry ()
#4  0x0000000100059177 in PyDict_SetItem ()
#5  0x000000010005d286 in _PyModule_Clear ()
#6  0x00000001000df8cd in PyImport_Cleanup ()
#7  0x00000001000f0027 in Py_Finalize ()
#8  0x0000000100107e1b in Py_Main ()
#9  0x0000000100000f54 in start ()
因此,segfault发生在我的python代码之外。我提到,如果我从ipython内部运行代码,或者将解释器/ipython更改为Enthound发行版中的解释器/ipython,或者如果我将Cython从1.9.1降级到1.6,那么问题仍然存在

<> >强> C++中的内存泄漏< /强>

<>因为这可能是内存泄漏(请让我知道如果有其他可能的解释)在C++代码中,我在C++类的C++测试代码上运行Valgrind,但是没有发现任何问题。(我不是100%确定它没有问题,因为我使用的是OSX Mountain Lion,尽管使用了最新的主干版本Valgrind,但它也存在问题。我使用的是OSX10.8抑制文件,建议先使用一个)。不管怎样,C++类不使用新的/DELTE/MALC/C/FILE,所以应该是好的。 Cython(?)中的内存泄漏

我尝试在崩溃的python代码上运行valgrind。除了上面提到的OSX抑制文件之外,我还添加了python抑制。Valgrind生成大量输出,然后崩溃。在输出中没有任何对我的源代码的引用。这是被指控的cython代码:

def split_props(np.ndarray[fptype, ndim=1, mode="c"] x,
                   np.ndarray[fptype, ndim=1, mode="c"] y,
                   np.ndarray[fptype, ndim=1, mode="c"] ylines):

cdef np.ndarray[fptype, ndim = 1, mode = "c"] areas = np.zeros((ylines.shape[0] + 1), dtype=np.float64, order="c")
cdef np.ndarray[fptype, ndim = 1, mode = "c"] static_moments_x = np.zeros((ylines.shape[0] + 1), dtype=np.float64, order="c")
cdef np.ndarray[fptype, ndim = 1, mode = "c"] inertia_moments_xx = np.zeros((ylines.shape[0] + 1), dtype=np.float64, order="c")

cdef SplitPolygon * SPINSTANCE = new SplitPolygon(100, 100)

SPINSTANCE.split_props(& x[0],  # = <fptype *> x.data
                         & y[0],
                         x.shape[0],
                         & ylines[0],
                         ylines.shape[0],
                         & areas[0],
                         & static_moments_x[0],
                         & inertia_moments_xx[0]
                         )
del SPINSTANCE
return areas, static_moments_x, inertia_moments_xx

现在,我真的被困在这一点上了。cython代码对你来说好看吗?是否有任何测试案例我可以编码来检查C++类分割多边形是否真的是无泄漏的?崩溃会因为其他原因发生吗?

谢谢您的评论。正如您所指出的,这不是内存泄漏

问题出在数组
x,y,ylines
中传递的数据中,这是错误的,因为它不遵守类
SplitPol()
的规范

这导致
SplitPols.split_props()
出现未定义的行为,在这种情况下,该行为是在调用
SPINSTANCE.split_props()
时通过地址传递的3个数组的边界之外写入

numpy通过对
zeros()
的3次调用来分配这三个数组。损坏的内存就在它们的附近,从一次运行到另一次运行,它可能属于一个关键的Python对象,导致segfault,或者没有,看起来一切正常


除了拧紧内存外,
SplitPols.split_props()
代码返回的数据是正确的,这没有任何帮助。

听起来根本不像内存泄漏!听起来好像某个东西的析构函数取决于刚刚被破坏的东西,取决于东西被破坏的顺序,它有时起作用,有时不起作用;这只会浪费越来越多的内存。
def SplitCirc(np.ndarray[fptype, ndim=1, mode="c"] ycenters,
               np.ndarray[fptype, ndim=1, mode="c"] radii,
               np.ndarray[fptype, ndim=1, mode="c"] ylines):

cdef np.ndarray[fptype, ndim = 1, mode = "c"] areas = np.zeros((len(ylines) + 1), dtype=np.float64, order="c")
cdef np.ndarray[fptype, ndim = 1, mode = "c"] static_moments_x = np.zeros((len(ylines) + 1), dtype=np.float64, order="c")
cdef np.ndarray[fptype, ndim = 1, mode = "c"] inertia_moments_xx = np.zeros((len(ylines) + 1), dtype=np.float64, order="c")

split_circles(& ycenters[0], & radii[0], len(ycenters),
              & ylines[0], len(ylines),
              & areas[0], & static_moments_x[0], & inertia_moments_xx[0])
return areas, static_moments_x, inertia_moments_xx