我很难接受Cython manual中的教科书PyMem_*
实现(我在IPython shell中):
In [2]: %%cython -f
...: from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
...: from libc.string cimport memcpy
...: cdef class A:
...: cdef unsigned char **data
...: def __cinit__(self):
...: print('Allocating memory.')
...: self.data = <unsigned char **>PyMem_Malloc(6)
...: if not self.data:
...: raise MemoryError()
...:
...: cpdef void assign(self):
...: cdef unsigned char a1[3]
...: cdef unsigned char a2[3]
...: a1 = bytearray(b'123')
...: a2 = bytearray(b'abc')
...: print('Assigning a1.')
...: memcpy(self.data[0], a1, 3)
...: print('Assigning a2.')
...: memcpy(self.data[1], a2, 3)
...: print(self.data[1][: 3])
...:
...: def __dealloc__(self):
...: print('Releasing memory.')
...: PyMem_Free(self.data)
...: a = A()
...: a.assign()
...: del(a)
...: b = A()
...: b.assign()
...: del(b)
Allocating memory.
Assigning a1.
Assigning a2.
Segmentation fault (core dumped)
我的代码有什么问题?我从手动示例中看到的唯一区别是我使用的是二维字符数组(它们不是NUL终止的字符串),所以也许我在这里做错了什么?
编辑
段错误发生在随机点。我将实例化和删除行加倍,因为大多数情况下,这是在第二遍执行的。或者即使我连续两次运行相同的Cython单元。
谢谢。
答案 0 :(得分:1)
根据评论(谢谢!),我重新设计了代码,以使用带有“步幅”的一维数组:
In [8]: %%cython -f
...: from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
...: from libc.string cimport memcpy
...: cdef class A:
...: cdef:
...: unsigned char *data
...: size_t ct, itemsize, size
...:
...: def __cinit__(self, size_t ct, size_t itemsize):
...: print('Allocating memory.')
...: self.data = <unsigned char *>PyMem_Malloc(ct * itemsize)
...: if not self.data:
...: raise MemoryError()
...: self.ct = ct
...: self.itemsize = itemsize
...: self.size = self.ct * self.itemsize
...:
...: cpdef void assign(self):
...: cdef unsigned char a1[3]
...: cdef unsigned char a2[3]
...: a1 = bytearray(b'123')
...: a2 = bytearray(b'abc')
...: print('Assigning a1.')
...: memcpy(self.data, a1, self.itemsize)
...: print('Assigning a2.')
...: memcpy(self.data + self.itemsize, a2, self.itemsize)
...: print(self.data[: self.itemsize])
...: print(self.data[self.itemsize: self.itemsize * 2])
...:
...: def __dealloc__(self):
...: print('Releasing memory.')
...: PyMem_Free(self.data)
...: a = A(2, 3)
...: a.assign()
...: del(a)
Allocating memory.
Assigning a1.
Assigning a2.
b'123'
b'abc'
Releasing memory.
这按预期工作。