pythoncextension+;多次调用python文件后崩溃。

pythoncextension+;多次调用python文件后崩溃。,python,c,extension-methods,Python,C,Extension Methods,我一直在使用一个Python-C扩展,其中Python文件以列表(数组)的形式传递给C文件,C文件返回三个double。 第一次调用测试文件(它导入c文件并调用c函数)时,程序工作正常。但是,如果我再次调用测试文件,程序将冻结,永远无法执行。 我不知道问题发生在哪里。我有一种感觉,这与c文件永不停止执行有关,如果可能或有意义的话 此外,我正在对变量进行mallocing和free,所以这不是一个问题 我的C API如下所示: 谢谢你 #include <Python.h> #incl

我一直在使用一个Python-C扩展,其中Python文件以列表(数组)的形式传递给C文件,C文件返回三个double。 第一次调用测试文件(它导入c文件并调用c函数)时,程序工作正常。但是,如果我再次调用测试文件,程序将冻结,永远无法执行。 我不知道问题发生在哪里。我有一种感觉,这与c文件永不停止执行有关,如果可能或有意义的话

此外,我正在对变量进行mallocing和free,所以这不是一个问题

我的C API如下所示:

谢谢你

#include <Python.h>
#include <stdio.h>
#include <stdlib.h>
#include "workingHyperbolic.c"

PyObject* py_fit(PyObject* self, PyObject* args)
{
    PyObject* seqx;
    PyObject* seqy;
    double p[3] = {1, 1, 1};           /* Initial conditions */
    double *carrayx;
    double *carrayy;
    double c, d, a;
    int seqlen;
    int i;

    /* get argument as a sequence */
    if(!PyArg_ParseTuple(args, "OO", &seqx, &seqy))                 //ParseTuple converts values from Python to C representation. By calling NULL, the appropriate extension is raised
        return NULL;
    seqx = PySequence_Fast(seqx, "argument must be iterable");
    seqy = PySequence_Fast(seqy, "argument must be iterable");
    if(!seqx)
        return 0;
    if(!seqy)
        return 0;
    /* prepare data as an array of doubles */
    seqlen = PySequence_Fast_GET_SIZE(seqx);            // get length of the object, assuming that the seqx is not NULL - faster than Pysequence_Size because seqx is a list or tuple
    carrayx = malloc(seqlen*sizeof(double));        //Allocates n bytes and returns a pointer of type void* to the allocated memory
    carrayy = malloc(seqlen*sizeof(double));
    if(!carrayx) {
        Py_DECREF(seqx);                                // CPython Garbage Collector uses "Reference Counting" to maintain a list of references to an object.
                                                        //If reference count fallst oz ero than garbage collector can deallocate space for that object.
        return PyErr_NoMemory(  );
    }
    if(!carrayy) {
        Py_DECREF(seqy);
        return PyErr_NoMemory(  );
    }
    for(i=0; i < seqlen; i++) {
        PyObject *fitemx;
        PyObject *fitemy;
        PyObject *itemx = PySequence_Fast_GET_ITEM(seqx, i);            //Return the sequence seqx as a list,
        PyObject *itemy = PySequence_Fast_GET_ITEM(seqy, i);
        if(!itemx) {
            Py_DECREF(seqx);
            free(carrayx);
            return 0;
        }
        if(!itemy) {
            Py_DECREF(seqy);
            free(carrayy);
            return 0;
        }
        fitemx = PyNumber_Float(itemx);                 //Returns the itemx converted to a float object on success,
        fitemy = PyNumber_Float(itemy);
        if(!fitemx) {
            Py_DECREF(seqx);
            free(carrayx);
            PyErr_SetString(PyExc_TypeError, "all items must be numbers");
            return 0;
        }
        if(!fitemy) {
            Py_DECREF(seqy);
            free(carrayy);
            PyErr_SetString(PyExc_TypeError, "all items must be numbers");
            return 0;
        }
        carrayx[i] = PyFloat_AS_DOUBLE(fitemx);             //Returns the C double value of Python float x, very fast, without error checking.
        carrayy[i] = PyFloat_AS_DOUBLE(fitemy);             //Returns the C double value of Python float x, very fast, without error checking.
        PyErr_Occurred();
        Py_XDECREF(fitemx);
        Py_XDECREF(fitemy);
    }

    /* clean up, compute, and return result */
    Py_DECREF(seqx);
    Py_DECREF(seqy);
    c = getParameters(carrayx, carrayy, p, 'c');
    d = getParameters(carrayx, carrayy, p, 'd');
    a = getParameters(carrayx, carrayy, p, 'a');
    printf("\n%lf", c);
    printf("\n%lf", d);
    printf("\n%lf", a);
    free(carrayx);
    free(carrayy);
    return Py_BuildValue("ddd", c,d,a);         // creates python objects FROM C data type to return result back to Python. 
}

// static PyObject *_raise_error(PyObject *py_fit) {
    // PyErr_SetString(PyExc_ValueError, "Vaue Error");
    // PyErr_SetString(PyExc_BaseException, "Base Error");
    // PyErr_SetString(PyExc_Exception, "Exception");
    // PyErr_SetString(PyExc_ArithmeticError, "Arithmetic");
    // PyErr_SetString(PyExc_LookupError, "PyExc_LookupError");
    // PyErr_SetString(PyExc_AssertionError, "PyExc_AssertionError");
    // PyErr_SetString(PyExc_AttributeError, "PyExc_AttributeError");
    // PyErr_SetString(PyExc_BlockingIOError, "PyExc_BlockingIOError");
    // PyErr_SetString(PyExc_FloatingPointError, "PyExc_FloatingPointError.");
    // PyErr_SetString(PyExc_EOFError, "PyExc_EOFError");
    // return Py_RETURN_NONE;
// }

/* DECLARATION OF METHODS*/
 PyMethodDef methods[] = {
    {"fit",(PyCFunction)py_fit, METH_VARARGS, "Descirption"},
    {NULL,NULL,0,NULL}
};

// Module Definition Structure
 struct PyModuleDef fittermod = {
   PyModuleDef_HEAD_INIT,"fit", NULL, -1, methods
};
#包括
#包括
#包括
#包括“working.c”
PyObject*py_-fit(PyObject*self,PyObject*args)
{
PyObject*seqx;
PyObject*seqy;
双p[3]={1,1,1};/*初始条件*/
双倍*carrayx;
双*卡雷伊;
双c,d,a;
内特赛克伦;
int i;
/*将参数作为序列获取*/
如果(!PyArg_ParseTuple(args,“OO”,&seqx,&seqy))//ParseTuple将值从Python转换为C表示形式。通过调用NULL,将引发相应的扩展
返回NULL;
seqx=PySequence_Fast(seqx,“参数必须是可写的”);
seqy=PySequence_Fast(seqy,“参数必须是可写的”);
如果(!seqx)
返回0;
如果(!sexy)
返回0;
/*以双精度数组的形式准备数据*/
seqlen=PySequence_Fast_GET_SIZE(seqx);//获取对象的长度,假设seqx不是NULL-比PySequence_SIZE快,因为seqx是列表或元组
carrayx=malloc(seqlen*sizeof(double));//分配n个字节并返回void*类型的指针到分配的内存
carrayy=malloc(seqlen*sizeof(双));
如果(!carrayx){
Py_DECREF(seqx);//CPython垃圾收集器使用“引用计数”来维护对对象的引用列表。
//如果引用计数下降,则垃圾收集器可以为该对象释放空间。
返回PyErr_nomery();
}
如果(!carrayy){
Py_DECREF(seqy);
返回PyErr_nomery();
}
对于(i=0;i
谢谢大家!问题是传递一个与我的另一个c例程不兼容的参数(参数p)

如果
carrayy
NULL
carrayx
为空,则在python扩展中可能会泄漏资源,这可能非常糟糕。@iharob:你说carrayy为NULL而carrayx不为空是什么意思?你一再犯同样的错误。我会重写整个函数。如果
itemx
NULL
您可以
free()
carrayx
但是您没有
free()
carrayy
,那么当它显然已经成功时,您也可以调用
PyError\u occurrent()
。同时发布python代码,我怀疑您传递的不是序列,而是列表。@iharob:谢谢,但我不太明白。我想如果我检查一个是