Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在同一地址Cython+;努比_Python_Arrays_Numpy_Memory_Cython - Fatal编程技术网

Python 在同一地址Cython+;努比

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

我在使用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 *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>和 A2也是悬空PoSoSok谢谢您的回答。您的C++示例是错误的。只要cfunc不将指针保留在某个位置,您的第一个调用就不会生成悬空指针。您可能想写的是:
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())