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)
精彩评论