I've read about numpy.frombuffer, but can't find any way to create array from pointer.
Asked
Active
Viewed 1.1k times
11
-
This question is answered here: http://stackoverflow.com/questions/8708758/can-i-force-a-numpy-ndarray-to-take-ownership-of-its-memory – ebarr May 29 '14 at 11:21
1 Answers
21
As pointed out in the comments above, you can use numpy.ctypeslib.as_array
:
numpy.ctypeslib.as_array(obj, shape=None)
Create a numpy array from a ctypes array or a ctypes POINTER. The numpy array shares the memory with the ctypes object.
The size parameter must be given if converting from a ctypes POINTER. The size parameter is ignored if converting from a ctypes array
So let's mimic a C function returning a pointer with a call to malloc
:
import ctypes as C
from ctypes.util import find_library
import numpy as np
SIZE = 10
libc = C.CDLL(find_library('c'))
libc.malloc.restype = C.c_void_p
# get a pointer to a block of data from malloc
data_pointer = libc.malloc(SIZE * C.sizeof(C.c_int))
data_pointer = C.cast(data_pointer,C.POINTER(C.c_int))
You can now make the data this pointer points to available to numpy
new_array = np.ctypeslib.as_array(data_pointer,shape=(SIZE,))
And to prove that they are accessing the same memory:
new_array[:] = range(SIZE)
print "Numpy array:",new_array[:SIZE]
print "Data pointer: ",data_pointer[:SIZE]
should output:
Numpy array: [0 1 2 3 4 5 6 7 8 9]
Data pointer: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
As a final note remember that the numpy array does not own its memory so explicit calls to free are required to avoid memory leaks.
del new_array
libc.free(data_pointer)

ebarr
- 7,704
- 1
- 29
- 40
-
1The library may be using a custom allocator, or on Windows in particular it could be linked with a different CRT. In general the library should export a function to `free` memory that it allocates. – Eryk Sun May 29 '14 at 13:34
-
Each call to `as_array` for a new pointer has to create and store an `__array_interface__` on the pointer. I recall a question that complained about the performance of this. Using an array type or a `c_void_p` subclass created by `ndpointer` doesn't have this cost, but it's not as flexible. – Eryk Sun May 29 '14 at 13:43