Can I force a numpy ndarray to take ownership of its memory?

前端 未结 2 1034
轮回少年
轮回少年 2020-12-29 11:03

I have a C function that mallocs() and populates a 2D array of floats. It \"returns\" that address and the size of the array. The signature is

int get_arra         


        
相关标签:
2条回答
  • 2020-12-29 11:26

    I just stumbled upon this question, which is still an issue in August 2013. Numpy is really picky about the OWNDATA flag: There is no way it can be modified on the Python level, so ctypes will most likely not be able to do this. On the numpy C-API level - and now we are talking about a completely different way of making Python extension modules - one has to explicitly set the flag with:

    PyArray_ENABLEFLAGS(arr, NPY_ARRAY_OWNDATA);
    

    On numpy < 1.7, one had to be even more explicit:

    ((PyArrayObject*)arr)->flags |= NPY_OWNDATA;
    

    If one has any control over the underlying C function/library, the best solution is to pass it an empty numpy array of the appropriate size from Python to store the result in. The basic principle is that memory allocation should always be done on the highest level possible, in this case on the level of the Python interpreter.


    As kynan commented below, if you use Cython, you have to expose the function PyArray_ENABLEFLAGS manually, see this post Force NumPy ndarray to take ownership of its memory in Cython.

    The relevant documentation is here and here.

    0 讨论(0)
  • 2020-12-29 11:27

    I would tend to have two functions exported from my C library:

    int get_array_c_nomalloc(float* addr, int nrows, int ncols); /* Pass addr as argument */
    int get_array_c(float **addr, int nrows, int ncols); /* Calls function above */
    

    I would then write my Python wrapper[1] of get_array_c to allocate the array, then call get_array_c_nomalloc. Then Python does own the memory. You could integrate this wrapper into your library so your user never has to be aware of get_array_c_nomalloc's existence.

    [1] This isn't really a wrapper anymore, but instead is an adapter.

    0 讨论(0)
提交回复
热议问题