Python ctypes '段错误: 11

0 投票
1 回答
724 浏览
提问于 2025-05-16 18:45

编辑: 这是一个新的例子,它会出错,但不需要改变 ulimit,而且 c 部分的内容无关紧要。

我是一名 Python 用户(我是在 edX 课程上学的),我在使用 ctypes 和 C 语言(但我其实对 C 语言不太了解)。当我用一些特定的参数(基本上是一个很大的数组大小)运行我的代码时,遇到了“Segmentation fault: 11”的问题。下面是一个小例子,展示了我的代码是怎么回事:

test1.py:

import numpy as np
from numpy.ctypeslib import ndpointer
import ctypes as cy


Lib_Path = './lib.so'

class Simulacion:
    def __init__(self, ss,tm):
        self.tm    = tm;
        self.ss    = ss;

    def ejecutar(self):
        self.data   = np.empty((int(self.ss), self.tm), dtype = float)
        lib   = cy.CDLL(Lib_Path)
        dblc = cy.c_double; pntrc = ndpointer(dblc);  intc = cy.c_long
        lib.trisolve.argtypes = [intc, pntrc, intc]
        lib.trisolve(self.tm, self.data, self.ss)
        return self.data

ss = 10
tm  = int(1e6);

sim = Simulacion(ss,tm)
data = sim.ejecutar()

test1.c

void trisolve(int tm, double* data, int ss){

}

makefile

SRC=test1
GCC=gcc-6
all:
    $(GCC) -fPIC -fopenmp -lm -c -O3 $(SRC).c
    $(GCC) -shared -lgomp -o lib.so $(SRC).o
clean:
    rm lib.so
    rm $(SRC).o

这段代码会出错,但不需要改变 ulimit。

在我的真实代码中,我使用“ulimit -s 65532”,这是我 Mac 上的最大栈大小。这限制了我使用的数组大小,而我现在需要将它的大小加倍。根据我所发现的问题,数组被存储在栈上,而不是堆上,因此我受到操作系统的限制。

所以我的问题是,如何将这个大数组传递给 C 语言,存储在堆上,然后再带回 Python?

我主要使用 Python,而 C 语言部分的代码我并没有经过很好的培训,所以“栈”、“堆”以及可能的“malloc”这些术语对我来说都是新的。

谢谢!

相关问题:

  • 暂无相关问题
暂无标签

1 个回答

1

最后我找到了问题,跟ctypes没有关系。在我的真实C代码中,我定义了一个数组,使用的是array[tm],但是tm的值太大,超出了栈的容量。为什么我能用上面的代码重现这个问题呢?我也不太清楚,但今天我尝试了一下(因为@eryksun说他的代码可以正常运行),结果没有出错。感谢大家的帮助;我以后会努力多学一点C语言。

撰写回答