python - 如何释放在 SWIG 的自定义构造函数中分配的内存?

标签 python c++ memory-management swig

我有一个关于 SWIG 的内存管理问题。

我在 C++ (TestStruct.h) 中有这个对象:

struct Buffer {
    uint8_t* data;
    int length;
}

我希望能够使用 python 列表或字符串初始化这个对象,并在没有内存泄漏的情况下从 python 中销毁它。 我的痛饮文件是:

%module test

%newobject Buffer;
%nodefaultctor Buffer;
%nodefaultdtor Buffer;

%{
    #include "TestStruct.h"
%}

%include "TestStruct.h"

%extend Buffer {
    Buffer(PyObject* inputList)
    {
        int leng = (int)PySequence_Length(inputList);
        uint8_t* temp = new uint8_t[leng];
        cout << "Buffer Constructor called: " << leng << "  " << (unsigned int)temp << endl;
        for(int i=0; i<leng; i++){
            PyObject *o = PySequence_GetItem(inputList,i);
            if (PyNumber_Check(o)) {
                temp[i] = (uint8_t) PyLong_AsLong(o);
                //cout << "uint8_t to C++: " << (int)temp[i] << endl;
            } else {
                PyErr_SetString(PyExc_ValueError,"Sequence elements must be integers");      
                return NULL;
            }
        }    
        Buffer* buff = new Buffer();
        buff->dataBuf = temp;
        buff->length = leng;
        return buff;
    }

    ~Buffer() {
        cout << "Buffer Destructor called: " << $self->length << "  " << (unsigned int)$self->dataBuf << endl;
        delete[] $self->dataBuf;
        delete $self;
    }
}

运行下面的简单测试会使 Python 的内存使用量飙升至 30MB

import test
import sys
import time

times = 1000
printsteps = False
print("performing memory stress test")
for j in range(times):
    sizeBytes = 1024 * 1
    input_list = list(range(sizeBytes))
    buffer = test.Buffer(input_list)

    del buffer 
    time.sleep(0.001)

每次循环运行时,都会调用构造函数和析构函数(我用打印输出验证了这一点),但它不会解决内存分配问题。

我需要 Buffer 将其作为参数传递给另一个 SWIG 包装的函数,并且我希望能够使用 Python 列表创建 Buffer 的数据。我尝试使用大致相同的代码使用类型映射(in 和 freearg),但它失败了。所以我想出了使用自定义构造函数和析构函数,但它不会解决内存泄漏的问题。欢迎任何输入

最佳答案

您在将 Python 列表转换为 C++ uint8_t[leng] 时对 Python C-API 的使用不正确并导致内存泄漏。重点是函数 PySequence_GetItem() 返回序列项的新引用。因为您未能对该项目调用 Py_DECREF(),所以当列表本身被删除时,Python 不会释放该项目的内存。

要修复,您只需在 for 循环中添加 Py_DECREF(o);

顺便说一下,Python 循环中的 del buffer 行是多余的。

关于python - 如何释放在 SWIG 的自定义构造函数中分配的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37186737/

相关文章:

python - 从 4 个角颜色插值的二维颜色渐变(256x256 矩阵)

c++ - ifstream 无法打开文件

c++ - 在 C++ 中重载运算符给我一个错误

c++ - 为什么两个 malloc 之间多了一行 8 字节?

c++ - 分配新 vector 时的 std::bad_alloc - 我能做什么

python - Django 过滤器反向外键

python - 基于 str.find 的 Pandas 切片字符串作为开始和停止的位置

c++ - Foreach 范围迭代 vector<int> - auto 或 auto&?

c++ - 我可以只使用固定数组而不是内存池吗?

Python Selenium Firefox - 不安全连接错误警报