我正在使用Python 2.7.3
在Ubuntu上编程。
我正在使用CFFI来填充Python列表,其中包含来自某些C代码的值 该列表相当大:打印时长约71 000个字符。
C代码使用了很多库。因此,以下代码仅用于更好地理解正在发生的事情。
datas_list = []
for i in range( 0, x ):
c_pDataStructure = ffi.new( "c_DataStructure[]", 1 ) // Create a pointer to the data structure
c.SomeCFunction( c_pDataStructure ) // Populate the data structure
datas_list.append( c.GetSomeInfo( c_pDataStructure ) ) // Get some info from the data structure
c.FreeDataStructure( c_pDataStructure ) // Release dynamically allocated memory
该程序使用Wingware IDE运行良好,但在从命令行启动时结束时出现glibc错误(*** glibc detected *** python: free(): invalid next size (fast): 0x0000000003b0b080 ***
):
c_pDataStructure = ffi.new( "c_Datastructure[]", 1)
在阅读了wim answer之后,我检查了IDE和命令行是否使用相同的解释器运行代码 - 它们是(/usr/bin/python
)。
编辑(valgrind报告):
==5089== Process terminating with default action of signal 11 (SIGSEGV)
==5089== General Protection Fault
==5089== at 0x54FBB0: PyObject_Malloc (in /usr/bin/python2.7)
==5089== by 0x10B30625: allocate_owning_object (_cffi_backend.c:2972)
==5089== by 0x10B40EE8: allocate_with_allocator.constprop.84 (_cffi_backend.c:3032)
==5089== by 0x10B41010: direct_newp (_cffi_backend.c:3153)
==5089== by 0x10B4138C: b_newp (_cffi_backend.c:3177)
==5089== by 0x4F95A4: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x5008C1: PyEval_EvalCodeEx (in /usr/bin/python2.7)
==5089== by 0x4F9AB7: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x4F9D01: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x4F9D01: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x4F9D01: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==5089== by 0x4F9D01: PyEval_EvalFrameEx (in /usr/bin/python2.7)
修改
以下是有关C数据结构的更多信息。这是它的外观:
typedef struct _STRUCT3{
some int, char*
}STRUCT3, *PSTRUCT3;
typedef struct _STRUCT2{
some int
PSTRUCT3 pStruct3;
}STRUCT3, *PSTRUCT3;
typedef struct _STRUCT1{
some int, char*
PSTRUCT2 pStruct2;
}STRUCT1, *PSTRUCT1;
我做了一个小C程序来分配/解除分配一个完整的C结构,而valgrind
没有发现任何内存泄漏。
问题:
valgrind
报告的确切含义是什么?-u (unbuffered)
来运行程序,但将其添加到命令行没有任何区别。ffi.gc( c_pDataStructure, c.FreeDataStructure )
吗?答案 0 :(得分:0)
我找到了解决问题的方法:
我使用ffi.gc(cdata, destructor)
来创建结构。我的Python代码现在看起来像:
data_list = []
for i in range( 0, x ):
# Create a pointer to the data structure and tell the garbage collector how to destroy it
gc_c_pDataStructure = ffi.gc( c.CreateDataStructure(), c.FreeDataStructure )
c.SomeCFunction( gc_c_pDataStructure ) # Populate the data structure
datas_list.append( c.GetSomeInfo( gc_c_pDataStructure ) ) # Store some data
以下是与ffi.gc()
相关的一些链接:
这里是创建数据结构的C函数(根据问题的结构示例):
PSTRUCT1 CreateDataStructure()
{
PSTRUCT1 pStruct1 = ( PSTRUCT1 ) malloc( sizeof( STRUCT1 ) );
_SetDummyValues( pStruct1 );
return pStruct1;
}
如您所见,我必须创建函数void _SetDummyValues( PSTRUCT1 pStruct1 )
。该函数将给定的结构指针设置为NULL。
答案 1 :(得分:0)
这可能也与Coverity在某些方面发现的这个错误有关 我们的CFFI生成的代码:
x0 = (void *)alloca((size_t)datasize);
...
{
free(x0);
}
正如您所看到的,它在堆栈分配的内存上自由调用。