I have this C code:
test.c
#define max_size 9
#define max_value 11
char ** my_function(char my_string[]){
char **my_array = malloc(sizeof(char *) * max_size);
if (!my_array){
return NULL;
}
for( i = 0; i < max_size; i++){
my_array[i] = malloc(sizeof(char)*max_value+1);
if (!my_array[i]) {
free (my_array);
return NULL;
}
}
for( i = 0; i < max_size; i++){
// some code to set my_array[i]
}
return my_array;
}
Which I'm compiling with:
gcc -shared -Wl,-soname,libTest.so.1 -o _libTest.dll -fPIC test.c
And them I'm importing in Python like this:
test.py
from ctypes import *
from ctypes.util import find_library
libc = CDLL(find_library("c"))
my_lib = CDLL("_libTest.dll")
my_function = my_lib.my_function
my_function.argtypes = [c_char_p]
my_function.restype = POINTER(c_char_p)
my_string = "Hello World"
c_string = c_char_p(my_string)
res = my_function(c_string)
for i in xrange(9):
result = res[i]
# some code using with result
libc.free(result)
libc.free(res)
But this raises this error:
Traceback (most recent call last):
File "C:/Documents/Python/test.py", line 19, in <module>
libc.free(res)
WindowsError: exception: access violation reading 0x005206CA
As this answer states:
The error you get indicates that your program is trying to write to memory address XXXXX, but isn't supposed to be writing to that memory address.
The above answer them uses some other tecnhics which don't involve mallocing any memory, thus is useful in my case, and also because I'm not trying to write in the memory, I'm trying to free it.
The error doesn't raise in the above line libc.free(result)
, so the memory allocated inside the my_array is set free, but not the my_array.
If I were to free it in C:
for ( i = 0; i < max_size; i ++){
free(res[i]);
}
free(res);
Which would be the right way to do, no error would raise. But this seem to not work in Python.
So the title question: How do I free nested mallocs from a C shared library in Python (ctypes)?