如何创建固定大小的多维 cython 数组?

How do I create a Multidimensional cython array of fixed size?

我正在尝试将 python 列表列表转换为 cython 多维数组。 该列表有 300,000 个元素,每个元素都是 10 个整数的列表。对于这里随机创建的这种情况。只要我的 cython 多维数组不大于 [210000][10] 左右,我尝试的方法就可以正常工作。我的实际项目当然更复杂,但我相信如果我让这个例子在这里工作,剩下的就差不多了。

我有一个包含以下内容的 cython 文件“array_cy.pyx”:

cpdef doublearray(list list1):
    cdef int[200000][10] a
    cdef int i
    cdef int y
    cdef int j
    cdef int value = 0
    for i in range(200000):
        for y in range(10):
            a[i][y] = list1[i][y]
    print("doublearray")
    print(a[40000][6])

cpdef doublearray1(list list1):
    cdef int[300000][10] a
    cdef int i
    cdef int y
    cdef int value = 0
    for i in range(300000):
        for y in range(10):
            a[i][y] = list1[i][y]
    print("doublearray1")
    print(a[40000][6])

然后在 main.py 我有

    import array_cy
    import random


    list1 = []
    for i in range(300000):
        list2 = []
        for j in range(10):
            list2.append(random.randint(0, 22))
        list1.append(list2)
    array_cy.doublearray(list1)
    array_cy.doublearray1(list1)

输出为:

doublearray
4

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

所以函数 doublearray(list) 工作正常并且输出是预期的一些随机数。但是 doublearray1(list) 给出了 SIGSEGV。如果在 doublearray1(list) 中,我注释掉行

    print(a[40000][6])

它也通过了 witout 一个问题,这是有道理的,因为我从不尝试访问数组。我不明白为什么它不起作用。我认为在 C 中,数组中元素的限制将由硬件定义。我的目标是以某种方式将列表的 python 列表转换为 cython 多维数组,我可以在没有任何 python 交互的情况下访问它。

建议的问题是关于使用 malloc 我认为这是我需要的,但我仍然没有让它工作,因为如果我将这两个函数更改为:

cpdef doublearray(list list1):
    cdef int[200000][10] a = <int**> malloc(200000 * 10 * sizeof(int))
    cdef int i
    cdef int y
    cdef int j
    cdef int value = 0
    for i in range(200000):
        for y in range(10):
            a[i][y] = list1[i][y]
    print("doublearray")
    print(a[40000][6])

cpdef doublearray1(list list1):
    cdef int[300000][10] a = <int**> malloc(300000 * 10 * sizeof(int))
    cdef int i
    cdef int y
    cdef int value = 0
    for i in range(300000):
        for y in range(10):
            a[i][y] = list1[i][y]
    print("doublearray1")
    print(a[40000][6])


仍然只有较小​​的数组有效。

在 C 中执行此操作的方法是将长度为 10 的列表列表转换为一维数组。并使用 malloc 分配足够的 space 并在之后释放它。另一种方法是使用指针数组。

cpdef doublearray1(list list1):
    cdef int *a = <int *> malloc(3000000*sizeof(int))
    cdef int i
    cdef int y
    cdef int value = 0
    for i in range(300000):
        for y in range(10):
            a[i*10+y] = list1[i][y]
    print("doublearray1")
    # same as a[2][5] in 2D-Array
    print(a[25])