0

我在 Ubuntu 上编程,使用Python 2.7.3.

我正在使用 CFFI 使用来自某些 C 代码的值填充 Python 列表。
该列表相当大:打印时大约有 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 detected *** python: free(): invalid next size (fast): 0x0000000003b0b080 ***在从命令行启动时以 glibc 错误 ( ) 结束,就在之前:

c_pDataStructure = ffi.new( "c_Datastructure[]", 1)  

在阅读了 wim 的回答后,我检查了 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报告究竟是什么意思?
  • 从 IDE 和命令行运行程序之间可能有什么区别?
    注意:IDE 使用 Python 参数-u (unbuffered)来运行程序,但将其添加到命令行没有任何区别。
  • 当我自己解除分配结构时,Python 的垃圾收集器是否在起作用?我应该ffi.gc( c_pDataStructure, c.FreeDataStructure )改用吗?
4

2 回答 2

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。

于 2016-03-31T16:46:25.327 回答
0

这也可能与 Coverity 在我们的一些 CFFI 生成的代码中发现的这个错误有关:

  x0 = (void *)alloca((size_t)datasize);
  ...
  { 
      free(x0); 
  }

如您所见,它在堆栈分配的内存上调用 free 。

于 2016-09-08T19:41:00.497 回答