【问题标题】:Python: ctypes + C malloc error. C memory problem or Python/ctypes problem?Python:ctypes + C malloc 错误。 C 内存问题还是 Python/ctypes 问题?
【发布时间】:2011-06-03 17:47:42
【问题描述】:

每个人。我在使用 ctypes 和 C 代码时出现内存分配错误。我想知道内存问题是在 C 内部,还是由 ctypes 使用不当引起的。内存错误是

python(79698) malloc: * 对象 0x15627ac08 的错误:已释放对象的校验和不正确 >- 对象可能在被释放后被修改。 * 在 malloc_error_break 中设置断点进行调试 中止

或

python(76110,0x7fff70062ca0) malloc: * 对象 0x7d807e1078907df 的错误:被释放的指针未分配 * 在 malloc_error_break 中设置断点进行调试 中止

取决于我如何编写下面代码的“free_some_memory”部分。我不会在这里贴一堆 C 代码,但假设我已经正确编写了 C 代码,我的 ctypes 界面看起来正确吗?

此外,对于给定版本的“free_some_memory”,我遇到的故障并不总是发生在我的脚本中的同一个地方。 是否有可能我的 C 代码内存管理写得不好,以至于 Python 内存管理可能会或可能不会搞砸(取消)分配?

不知道这是否重要,但我正在使用 Mac,Snow Leopard。
非常感谢您提供的任何帮助。

最好, jkmac

我的 C 代码如下所示:

/**** cfunction.c ****/
int cfun (double *y, char datafile[1024], int byteoffset, int num )
{
  allocate_some_memory;
  do_stuff;

  if ( error_condition )
  {
    free_some_memory;
    return ( -1 );
  }

  fill_y_here;
  free_some_memory;
  return ( 0 );
}

我的 ctypes 包装器看起来像:

#pyfunction.py

import ctypes as C
import numpy as np

lib = C.CDLL('mylib.dylib')

def pyfun(DATAFILE, BYTEOFFSET, NUM):
    """
    DATAFILE: a string file name
    BYTEOFFSET: an integer
    NUM: an integer
    """

    #return integer success/failure flag
    lib.cfun.restype = C.c_int 

    #array memory to be filled inside of C
    Y = np.empty(NUM,dtype='double',order='C')

    cDATAFILE = C.create_string_buffer(DATAFILE,1024) 
    cBYTEOFFSET = C.c_int(int(BYTEOFFSET))
    cNUM = C.c_int(int(NUM))

    flag = lib.cfun(Y.ctypes.data_as(C.POINTER(C.c_double)), \ 
               cDATAFILE,cBYTEOFFSET,cNUM)

    if flag == -1:
        print("Something went wrong.")
        return -1
    else:
        return Y

【问题讨论】:

  • 您需要发布 cfunction.c 的实际代码,而不是伪代码。
  • Python 代码没问题。贴出C代码。请注意,您可以将字符串、整数、指针直接传递给 C 函数,而无需将它们放入 ctypes 类型中(直接传递 DATAFILE、BYTEOFFSET、NUM 而无需 cDATAFILE 等翻译。
  • 感谢您查看此内容。我将生成一个生成问题的 C 的最小示例,因为我无法发布完整的代码。
  • 我在 OS X 上使用 Python GDLA 库时遇到了同样的问题,其中 brew 安装了 gdal 和 pip 安装了 gdal 1.10.1/1.10.0 有什么想法吗?

标签: python c malloc ctypes


【解决方案1】:

我遇到了这个问题,这是我想出来的:

如果你用 ctypes 映射一些东西然后释放它,当 ctypes 对象被销毁时你会得到一个错误。因此,在调用 free() 之前,需要确保在 python 代码中没有对它的剩余引用。

所以,你的 C 代码会是这样的:

char* p;
char* allocate() {
 p = asprintf("hello world");
 return(p)
}
void freep() {
 free(p);
}

你的 Python 代码会是这样的:

allocate = clib.allocate
allocate.restype = c_char_p()
p = allocate()
print p
# This is the key:
del(p)
clib.freep()

如果您想查看错误,只需省略 del(p)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-28
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 2011-02-17
    • 1970-01-01
    相关资源
    最近更新 更多