diff options
Diffstat (limited to 'docs/examples/tutorial/memory_allocation')
4 files changed, 102 insertions, 48 deletions
diff --git a/docs/examples/tutorial/memory_allocation/malloc.py b/docs/examples/tutorial/memory_allocation/malloc.py new file mode 100644 index 000000000..fb7e82236 --- /dev/null +++ b/docs/examples/tutorial/memory_allocation/malloc.py @@ -0,0 +1,24 @@ +import random +from cython.cimports.libc.stdlib import malloc, free + +def random_noise(number: cython.int = 1): + i: cython.int + # allocate number * sizeof(double) bytes of memory + my_array: cython.p_double = cython.cast(cython.p_double, malloc( + number * cython.sizeof(cython.double))) + if not my_array: + raise MemoryError() + + try: + ran = random.normalvariate + for i in range(number): + my_array[i] = ran(0, 1) + + # ... let's just assume we do some more heavy C calculations here to make up + # for the work that it takes to pack the C double values into Python float + # objects below, right after throwing away the existing objects above. + + return [x for x in my_array[:number]] + finally: + # return the previously allocated memory to the system + free(my_array) diff --git a/docs/examples/tutorial/memory_allocation/malloc.pyx b/docs/examples/tutorial/memory_allocation/malloc.pyx index e01a378e3..6aa583aab 100644 --- a/docs/examples/tutorial/memory_allocation/malloc.pyx +++ b/docs/examples/tutorial/memory_allocation/malloc.pyx @@ -1,23 +1,24 @@ -import random
-from libc.stdlib cimport malloc, free
-
-def random_noise(int number=1):
- cdef int i
- # allocate number * sizeof(double) bytes of memory
- cdef double *my_array = <double *> malloc(number * sizeof(double))
- if not my_array:
- raise MemoryError()
-
- try:
- ran = random.normalvariate
- for i in range(number):
- my_array[i] = ran(0, 1)
-
- # ... let's just assume we do some more heavy C calculations here to make up
- # for the work that it takes to pack the C double values into Python float
- # objects below, right after throwing away the existing objects above.
-
- return [x for x in my_array[:number]]
- finally:
- # return the previously allocated memory to the system
- free(my_array)
+import random +from libc.stdlib cimport malloc, free + +def random_noise(int number=1): + cdef int i + # allocate number * sizeof(double) bytes of memory + cdef double *my_array = <double *> malloc( + number * sizeof(double)) + if not my_array: + raise MemoryError() + + try: + ran = random.normalvariate + for i in range(number): + my_array[i] = ran(0, 1) + + # ... let's just assume we do some more heavy C calculations here to make up + # for the work that it takes to pack the C double values into Python float + # objects below, right after throwing away the existing objects above. + + return [x for x in my_array[:number]] + finally: + # return the previously allocated memory to the system + free(my_array) diff --git a/docs/examples/tutorial/memory_allocation/some_memory.py b/docs/examples/tutorial/memory_allocation/some_memory.py new file mode 100644 index 000000000..31ad63a6e --- /dev/null +++ b/docs/examples/tutorial/memory_allocation/some_memory.py @@ -0,0 +1,27 @@ +from cython.cimports.cpython.mem import PyMem_Malloc, PyMem_Realloc, PyMem_Free + +@cython.cclass +class SomeMemory: + data: cython.p_double + + def __cinit__(self, number: cython.size_t): + # allocate some memory (uninitialised, may contain arbitrary data) + self.data = cython.cast(cython.p_double, PyMem_Malloc( + number * cython.sizeof(cython.double))) + if not self.data: + raise MemoryError() + + def resize(self, new_number: cython.size_t): + # Allocates new_number * sizeof(double) bytes, + # preserving the current content and making a best-effort to + # re-use the original data location. + mem = cython.cast(cython.p_double, PyMem_Realloc( + self.data, new_number * cython.sizeof(cython.double))) + if not mem: + raise MemoryError() + # Only overwrite the pointer if the memory was really reallocated. + # On error (mem is NULL), the originally memory has not been freed. + self.data = mem + + def __dealloc__(self): + PyMem_Free(self.data) # no-op if self.data is NULL diff --git a/docs/examples/tutorial/memory_allocation/some_memory.pyx b/docs/examples/tutorial/memory_allocation/some_memory.pyx index 2e639ac4d..e6bb63b77 100644 --- a/docs/examples/tutorial/memory_allocation/some_memory.pyx +++ b/docs/examples/tutorial/memory_allocation/some_memory.pyx @@ -1,25 +1,27 @@ -from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
-
-cdef class SomeMemory:
-
- cdef double* data
-
- def __cinit__(self, size_t number):
- # allocate some memory (uninitialised, may contain arbitrary data)
- self.data = <double*> PyMem_Malloc(number * sizeof(double))
- if not self.data:
- raise MemoryError()
-
- def resize(self, size_t new_number):
- # Allocates new_number * sizeof(double) bytes,
- # preserving the current content and making a best-effort to
- # re-use the original data location.
- mem = <double*> PyMem_Realloc(self.data, new_number * sizeof(double))
- if not mem:
- raise MemoryError()
- # Only overwrite the pointer if the memory was really reallocated.
- # On error (mem is NULL), the originally memory has not been freed.
- self.data = mem
-
- def __dealloc__(self):
- PyMem_Free(self.data) # no-op if self.data is NULL
+from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free + + +cdef class SomeMemory: + cdef double* data + + def __cinit__(self, size_t number): + # allocate some memory (uninitialised, may contain arbitrary data) + self.data = <double*> PyMem_Malloc( + number * sizeof(double)) + if not self.data: + raise MemoryError() + + def resize(self, size_t new_number): + # Allocates new_number * sizeof(double) bytes, + # preserving the current content and making a best-effort to + # re-use the original data location. + mem = <double*> PyMem_Realloc( + self.data, new_number * sizeof(double)) + if not mem: + raise MemoryError() + # Only overwrite the pointer if the memory was really reallocated. + # On error (mem is NULL), the originally memory has not been freed. + self.data = mem + + def __dealloc__(self): + PyMem_Free(self.data) # no-op if self.data is NULL |