Python 在同一地址Cython+;努比
我在使用numpy+cython时遇到了一些有趣的内存行为,当时我试图将numpy数组作为C数组来获取数据,以便在无GIL函数中使用。我已经查看了cython和numpy的数组API,但没有找到任何解释。因此,考虑下面的代码行:Python 在同一地址Cython+;努比,python,arrays,numpy,memory,cython,Python,Arrays,Numpy,Memory,Cython,我在使用numpy+cython时遇到了一些有趣的内存行为,当时我试图将numpy数组作为C数组来获取数据,以便在无GIL函数中使用。我已经查看了cython和numpy的数组API,但没有找到任何解释。因此,考虑下面的代码行: cdef np.float32_t *a1 = <np.float32_t *>np.PyArray_DATA(np.empty(2, dtype="float32")) print "{0:x}".format(<unsigned int>a1
cdef np.float32_t *a1 = <np.float32_t *>np.PyArray_DATA(np.empty(2, dtype="float32"))
print "{0:x}".format(<unsigned int>a1)
cdef np.float32_t *a2 = <np.float32_t *>np.PyArray_DATA(np.empty(2, dtype="float32"))
print "{0:x}".format(<unsigned int>a2)[]
为什么?我通过在PyArray_数据调用之外声明我的numpy数组来解决这个问题,在这种情况下,我得到了我期望的结果
我能想到的唯一解释是,我不会在PyArray_数据函数的作用域之外创建任何Python对象,调用此函数不会增加Python的引用计数。因此,GC会立即回收这个内存空间,并在现在可用的上一个内存地址分配下一个数组。有没有比我更精通cython的人可以证实这一点或给出另一种解释?您创建了两个临时numpy数组,它们恰好位于同一个地址。由于没有为它们保留python引用,它们会立即被垃圾收集,
a1
和a2
也会成为悬空指针
如果为他们保留参考资料,他们的地址不能相同,例如:
cdef int[:] a = np.arange(10) # A memoryview will keep the numpy array from GC.
cdef int[:] b = np.arange(10)
cdef int* a_ptr = &a[0]
cdef int* b_ptr = &b[0]
print(<size_t>a_ptr)
print(<size_t>b_ptr)
正确的方式:
# make sure keep_me is alive before cfunc have finished with it.
cdef bytes keep_me = ("right" + "way").encode()
cfunc(temp)
# Or for single use.
cfunc(("right" + "way").encode())
// keep `keep_me` for later use.
string keep_me = string("right") + string("way");
cfunc(keep_me.c_str());
// Or, for single use.
cfunc((string("right") + string("way")).c_str())
< P> C++中的另一个例子:代码STD::String < /Cuth>成员>代码> CyString():/> >: 正确的方式:
# make sure keep_me is alive before cfunc have finished with it.
cdef bytes keep_me = ("right" + "way").encode()
cfunc(temp)
# Or for single use.
cfunc(("right" + "way").encode())
// keep `keep_me` for later use.
string keep_me = string("right") + string("way");
cfunc(keep_me.c_str());
// Or, for single use.
cfunc((string("right") + string("way")).c_str())
参考:创建两个临时numpy数组时,它们恰好位于同一地址。为什么称它们为临时numpy数组?这是否与我的解释有关,没有为它们保留python引用,因此它们是“临时的”。是的。他们立即被收集起来<代码> A1 < /C>和
const char*not_good=(string(“not”)+string(“good”)。c_str()//生成一个悬空指针
// keep `keep_me` for later use.
string keep_me = string("right") + string("way");
cfunc(keep_me.c_str());
// Or, for single use.
cfunc((string("right") + string("way")).c_str())