Python测试脚本的示例输出:
--------------------------------------------------------------------------------Works as expected: b0 = Buffer(0,) b1 = Buffer(1,1,) b0 = Buffer(0,) y = Buffer(0,) repr(b0) = Buffer(ID = 0,vector at 0x020bf450,data at 0x020aeb30,size = 6) repr(y) = Buffer(ID = 0,size = 6)Funny business: Deleting Buffer(ID = 2) Deleting Buffer(ID = 3) repr(b2) = Buffer(ID = 2,vector at 0x020bf790,data at 0x00,size = 4257068) Deleting Buffer(ID = 4) repr(b3) = Buffer(ID = 4,vector at 0x02037040,data at 0x0204a4e0,size = 6) Deleting Buffer(ID = 0) Deleting Buffer(ID = 1)
删除缓冲区(ID = X)是从Buffer :: ~Buffer()C代码中生成的,所以我们在这里可以看到,在Funny业务部分,C Buffer对象被过早删除了! Python对象b2和b3应该保持对ID = 2和ID = 4的C Buffer对象的引用.
我的所有代码都附在我的博客post上.但是,我将在这里总结一下代码:
Buffer.hpp:
#include <vector>#include <string>struct Buffer{ Buffer(); Buffer(const Buffer & copy); ~Buffer(); Buffer & operator=(const Buffer & rhs); Buffer & operator<<(const Buffer & rhs); Buffer & operator<<(double rhs); std::string __str__() const; std::string __repr__() const; private: std::vector<double> _data; int _ID;};
swig_test.i:
%module swig_test%include "std_string.i"%{ #include "Buffer.hpp" #include <iostream>%}%ignore Buffer::operator=;%include "Buffer.hpp"
go_test.py:
from swig_test import Bufferdef zeros(n): ''' Returns a Buffer filled with 'n' zeros. ''' b = Buffer() for i in xrange(n): b << 0.0 return bdef ones(n): ''' Returns a Buffer filled with 'n' ones. ''' b = Buffer() for i in xrange(n): b << 1.0 return bdef main(): #-------------------------------------------------------------------------- # This sections works as expected print "-" * 80 print "Works as expected:" b0 = zeros(3) print " b0 = ",b0 b1 = ones(3) print " b1 = ",b1 y = b0 << b1 print " b0 = ",b0 print " y = ",y print " b1 = ",b1 print " repr(b0) = ",repr(b0) print " repr(y) = ",repr(y) #-------------------------------------------------------------------------- # Funny things are happening here! print "Funny business:" b2 = zeros(3) << ones(3) print " repr(b2) = ",repr(b2) b3 = zeros(3) << 4.0 print " repr(b3) = ",repr(b3)if __name__ == "__main__": main()
我在博客文章中已经尝试了一些SWIG的东西,但我的SWIG-foo技能已经缩短了.
救救我社区,你是我唯一的希望!
更新1
我怀疑我有多个PyObjects将Buffer *保存到同一个C Buffer对象,所以当临时PyObject被垃圾收集时,它会删除C Buffer *.
所以,我想我需要一个Py_INCREF,但在哪里呢?
更新2
尝试按照jarod42的建议按值返回会破坏串联范例,例如:
b = Buffer()b << 1 << 2 << 3print b
只生产:
Buffer(1,)
所以这不是我想要的.
%newobject指令可用于释放函数或方法创建的新创建的对象(防止内存泄漏).在这种情况下,Buffer :: operator<<没有创建新对象.
解决方法 经过一番搜索后,我遇到了这个 thread,最终导致了一个有效的解决方案.将typemap(out)与Py_INCREF结合使用就可以了.
swig_test.i:
%module swig_test%include "std_string.i"%{ #include "Buffer.hpp" #include <iostream>%}%ignore Buffer::operator=;%typemap(out) Buffer & operator<<{ if(result) { /* suppress unused warning */ } Py_INCREF($self); $result = $self;}%include "Buffer.hpp"
现在我得到了我想要的行为(它与纯Python实现相匹配)并且没有内存泄漏.
总结以上是内存溢出为你收集整理的SWIG,C和Python:C临时对象过早删除全部内容,希望文章能够帮你解决SWIG,C和Python:C临时对象过早删除所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)