Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.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
C_Python不释放缓冲区内存_Python_C_Python 3.x_Python C Api - Fatal编程技术网

C_Python不释放缓冲区内存

C_Python不释放缓冲区内存,python,c,python-3.x,python-c-api,Python,C,Python 3.x,Python C Api,我正在为python编写C代码(python C API),我注意到python没有释放文件的内存,我想知道问题是否出在我的代码中。 我想尽量简化,但我希望不会遗漏任何细节。 该文件是带有缓冲区的二进制文件,前4个字节是缓冲区大小,然后是缓冲区。 二进制文件(big_file.comp): python代码(test.py): 一些C代码简化了: #include <Python.h> #include "structmember.h" typedef struct { P

我正在为python编写C代码(python C API),我注意到python没有释放文件的内存,我想知道问题是否出在我的代码中。 我想尽量简化,但我希望不会遗漏任何细节。 该文件是带有缓冲区的二进制文件,前4个字节是缓冲区大小,然后是缓冲区。

二进制文件(big_file.comp):

python代码(test.py):

一些C代码简化了

#include <Python.h>
#include "structmember.h"

typedef struct {
    PyObject_HEAD
    uint32_t arr_size;
} DecompressObject;


static int Decompress_init(DecompressObject *self, PyObject *args, PyObject *kwds){
    return 0;
}

static PyObject* Decompress_handle_buffer(DecompressObject* self, PyObject* args){
    uint32_t buf_size = 0;
    uint8_t *buf = NULL;

    // get buffer and buffer length from python function
    if(!PyArg_ParseTuple(args, "y*i", &buf, &buf_size)){
        PyErr_SetString(PyExc_Exception, "Failed to parse function arguments");
        return NULL;
    }

    self->arr_size = 10;
    Py_XINCREF(self);
    return (PyObject *) self;
}

static PyObject* Decompress_next(DecompressObject *self, PyObject *Py_UNUSED(ignored)){
    static uint32_t seq_index = 0;
    if (seq_index < self->arr_size) {
        seq_index++;
        Py_RETURN_NONE;
    }
    seq_index = 0;
    return NULL;
}

static void Decompress_dealloc(DecompressObject *self){
    Py_TYPE(self)->tp_free((PyObject *) self);
}


static PyMethodDef Decompress_methods[] = {
    {"decompress_buffer", (PyCFunction) Decompress_handle_buffer, METH_VARARGS, "Decompress a buffer to asc data."},
    {NULL}  /* Sentinel */
};

static PyTypeObject DecompressType = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "decomplib.Decompress",
    .tp_doc = "Decompress object",
    .tp_basicsize = sizeof(DecompressObject),
    .tp_itemsize = 0,
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
    .tp_alloc = PyType_GenericAlloc,
    .tp_new = PyType_GenericNew,
    .tp_iter = PyObject_SelfIter,
    .tp_init = (initproc) Decompress_init,
    .tp_dealloc = (destructor) Decompress_dealloc,
    .tp_iternext = (iternextfunc) Decompress_next,
    .tp_methods = Decompress_methods,
};

static PyModuleDef Decompressmodule = {
    PyModuleDef_HEAD_INIT,
    .m_name = "decomplib",
    .m_doc = "Decompress an compressed file.",
    .m_size = -1,
};


PyMODINIT_FUNC PyInit_decomplib(void){
    PyObject *d;
    if (PyType_Ready(&DecompressType) < 0)
        return NULL;

    d = PyModule_Create(&Decompressmodule);
    if (d == NULL)
        return NULL;

    Py_INCREF(&DecompressType);
    if (PyModule_AddObject(d, "Decompress", (PyObject *) &DecompressType) < 0) {
        Py_DECREF(&DecompressType);
        Py_DECREF(d);
        return NULL;
    }

    return d;
}
在玩游戏的时候,我注意到,如果我将
C
函数
解压\u handle\u buffer
中对函数
PyArg\u ParseTuple
的调用从
“y*I”
更改为
“Si”
,Python会清理内存

./test.py -f ~/Desktop/TEST_CAN_OPT/big_fie.comp
None
None
None
...
None
None
None
pmem(rss=22577152, vms=84869120, shared=6361088, text=2867200, lib=0, data=16420864, dirty=0)
但是,缓冲区未正确读取。
有什么想法吗?! 额外信息
  • 我正在使用虚拟机(VMware Workstation 15)
  • 操作系统Ubuntu 18.4
  • Python 3.6.9

    y*
    与您正在使用的
    uint8\t
    不一致。如中所述,它将填充您应该提供的结构


    您需要实际提供一个Py_缓冲区,当您使用完后,您需要释放缓冲区。

    非常感谢,我不知道我怎么会错过它。
    #include <Python.h>
    #include "structmember.h"
    
    typedef struct {
        PyObject_HEAD
        uint32_t arr_size;
    } DecompressObject;
    
    
    static int Decompress_init(DecompressObject *self, PyObject *args, PyObject *kwds){
        return 0;
    }
    
    static PyObject* Decompress_handle_buffer(DecompressObject* self, PyObject* args){
        uint32_t buf_size = 0;
        uint8_t *buf = NULL;
    
        // get buffer and buffer length from python function
        if(!PyArg_ParseTuple(args, "y*i", &buf, &buf_size)){
            PyErr_SetString(PyExc_Exception, "Failed to parse function arguments");
            return NULL;
        }
    
        self->arr_size = 10;
        Py_XINCREF(self);
        return (PyObject *) self;
    }
    
    static PyObject* Decompress_next(DecompressObject *self, PyObject *Py_UNUSED(ignored)){
        static uint32_t seq_index = 0;
        if (seq_index < self->arr_size) {
            seq_index++;
            Py_RETURN_NONE;
        }
        seq_index = 0;
        return NULL;
    }
    
    static void Decompress_dealloc(DecompressObject *self){
        Py_TYPE(self)->tp_free((PyObject *) self);
    }
    
    
    static PyMethodDef Decompress_methods[] = {
        {"decompress_buffer", (PyCFunction) Decompress_handle_buffer, METH_VARARGS, "Decompress a buffer to asc data."},
        {NULL}  /* Sentinel */
    };
    
    static PyTypeObject DecompressType = {
        PyVarObject_HEAD_INIT(NULL, 0)
        .tp_name = "decomplib.Decompress",
        .tp_doc = "Decompress object",
        .tp_basicsize = sizeof(DecompressObject),
        .tp_itemsize = 0,
        .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
        .tp_alloc = PyType_GenericAlloc,
        .tp_new = PyType_GenericNew,
        .tp_iter = PyObject_SelfIter,
        .tp_init = (initproc) Decompress_init,
        .tp_dealloc = (destructor) Decompress_dealloc,
        .tp_iternext = (iternextfunc) Decompress_next,
        .tp_methods = Decompress_methods,
    };
    
    static PyModuleDef Decompressmodule = {
        PyModuleDef_HEAD_INIT,
        .m_name = "decomplib",
        .m_doc = "Decompress an compressed file.",
        .m_size = -1,
    };
    
    
    PyMODINIT_FUNC PyInit_decomplib(void){
        PyObject *d;
        if (PyType_Ready(&DecompressType) < 0)
            return NULL;
    
        d = PyModule_Create(&Decompressmodule);
        if (d == NULL)
            return NULL;
    
        Py_INCREF(&DecompressType);
        if (PyModule_AddObject(d, "Decompress", (PyObject *) &DecompressType) < 0) {
            Py_DECREF(&DecompressType);
            Py_DECREF(d);
            return NULL;
        }
    
        return d;
    }
    
    ./test.py -f ~/Desktop/TEST_CAN_OPT/big_fie.comp
    None
    None
    None
    ...
    None
    None
    None
    pmem(rss=4349915136, vms=4412583936, shared=6270976, text=2867200, lib=0, data=4344135680, dirty=0)
    
    ./test.py -f ~/Desktop/TEST_CAN_OPT/big_fie.comp
    None
    None
    None
    ...
    None
    None
    None
    pmem(rss=22577152, vms=84869120, shared=6361088, text=2867200, lib=0, data=16420864, dirty=0)