Search code examples
pythonpointerscython

Does a pointer get freed when called indirectly in a function from a struct?


Say we have the following in Cython:

ctypedef struct Structure:
    int* array
    int size


cdef print_fx(Structure obj):
    print(obj.array[0])

cdef create_object(int size):
    cdef Structure result
    result.size = size
    result.array = <int*>malloc(size*sizeof(int))
    for i in range(size):
        result.array[i] = 1
    return result

And I want to use print_fx without explicitly creating the specific object:

print_fx(create_object(3))

If I were to write:

cdef Structure testobj = create_object(3)
print_fx(testobj)

free(testobj.array)

I have to free the pointer in the struct.

If I use it directly, print_fx(create_object(3)), does it get freed automatically after the Cell in Jupyter runs?


Solution

  • No, it won't. You will always have to free the malloced memory manually, otherwise it causes memory leak and your program or computer will crash eventually.

    %load_ext Cython
    

    %%cython
    from libc.stdlib cimport malloc, free
    cdef struct teststruct:
        int * array
        int size
    
    cdef teststruct create_object(int size):
        cdef teststruct result
        cdef int i
        result.size = size
        result.array = <int *> malloc(size * sizeof(int))
        for i in range(size):
            result.array[i] = 1
        return result
    
    lm = 100000
    
    def outer_func_1():
        cdef teststruct testobj = create_object(lm)
        i = testobj.array[0]
        free(testobj.array)
    
    def outer_func_2():
        i = create_object(lm).array[0]
    

    for i in range(1000000):
        outer_func_1() #will never crash no matter how many times it repeated
    

    for i in range(100000):
        outer_func_2() #crashed