开发者

Python: ctypes + C malloc error. C memory problem or Python/ctypes problem?

everyone. I'm having a memory allocation error using ctypes and a C code. I'm wondering if the memory problem is inside of C, or caused by an improper use of ctypes. The memory error is

python(79698) malloc: * error for object 0x15627ac08: incorrect checksum for freed object >- object was probably mo开发者_StackOverflow社区dified after being freed. * set a breakpoint in malloc_error_break to debug Abort

or

python(76110,0x7fff70062ca0) malloc: * error for object 0x7d807e1078907df: pointer being >freed was not allocated * set a breakpoint in malloc_error_break to debug Abort

depending on how I write the "free_some_memory" part of the code below. I won't post a bunch of C code here, but assuming I've written the C code correctly, does my ctypes interface look correct?

Also, the failures I'm experiencing don't always happen in the same place in my scripts, for a given version of "free_some_memory". Is it possible that my C code memory management is written poorly such that Python memory management may or may not bungle up (de)allocations?

Dunno if this is important, but I'm working on a Mac, Snow Leopard.

Any help you can offer would be very appreciated.

Best, jkmacc

My C code looks like:

/**** 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 );
}

My ctypes wrapper looks like:

#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


I had this problem and here is what I figured out:

If you map something with ctypes and then free it you will get an error when the ctypes object is destroyed. So, before you call free(), you need to make sure that there are no remaining references to it in the python code.

So, your C code will be like:

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

And your Python code will be like:

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

If you want to see an error, just omit del(p)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜