【发布时间】:2018-09-05 13:29:53
【问题描述】:
我在使用 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)[]
我使用 numpy 的空函数分配了两个 numpy 数组,并希望为每个数组检索指向数据缓冲区的指针。您会期望这两个指针指向堆上的两个不同内存地址,可能间隔 2*4 字节。但是不,我得到指向相同内存地址的指针,例如
>>>96a7aec0
>>>96a7aec0
怎么会?我设法通过在 PyArray_DATA 调用之外声明我的 numpy 数组来解决这个问题,在这种情况下,我得到了我所期望的。
我能想到的唯一解释是,我没有在 PyArray_DATA 函数的范围之外创建任何 Python 对象,并且调用此函数不会增加 Python 的引用计数。因此 GC 会立即回收这个内存空间,并且下一个数组被分配到现在空闲的前一个内存地址。比我更精通 cython 的人能否证实这一点或给出其他解释?
【问题讨论】:
-
你创建了两个临时的numpy数组,它们恰好在同一个地址。
-
为什么称它们为临时 numpy 数组?它是否与我的解释有关,没有为它们保留 python 参考,因此它们是“临时的”。
-
是的。它们会立即被垃圾收集。
a1和a2也是悬空指针 -
好的,谢谢你的回答。
标签: python arrays numpy memory cython