【问题标题】:PyRun_SimpleString call cause memory corruption?PyRun_SimpleString 调用导致内存损坏?
【发布时间】:2015-02-09 02:04:22
【问题描述】:

我正在尝试在 C++ 中使用 Python 并具有以下代码。我打算在用户输入路径上解析和执行 sys.path.append 。看起来对 PyRun_SimpleString 的调用导致某种溢出到类的私有类 var 中。这怎么发生的?我尝试了各种缓冲区大小 50、150、200,并没有改变输出。

class Myclass
{
    ...
    private:
        char *_modName;
        char *_modDir;
};
Myclass::Myclass()
{
    Py_Initialize();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString((char *)"sys.path.append('/home/userA/Python')");
}
Myclass::init()
{
    // this function is called before Myclass::test()
    // a couple other python funcitons are called as listed below. 
    // PyString_FromString, PyImport_Import, PyObject_GetAttrString, PyTuple_New, PyTuple_SetItem, PyObject_CallObject, PyDict_GetItemString
}
Myclass::test()
{
    char buffer[150];
    char *strP1 = (char *)"sys.path.append('";
    char *strP2 = (char *)"')";
    strcpy (buffer, strP1);
    strcat (buffer, _modDir);
    strcat (buffer, strP2);
    printf("Before %s\n", _modDir);
    printf("Before %s\n", _modName);
    PyRun_SimpleString(buffer);
    printf("After %s\n", _modName);
} 

这是输出。仅供参考,我使用 a,b,c,d,f 仅用于说明目的。它几乎像 PyRun_SimpleString(buffer) 一样将缓冲区的末尾粘贴到 _modName 中。

Before /aaa/bbb/ccc/ddd
Before ffffff
After cc/ddd'

【问题讨论】:

  • _modName 是如何初始化的?初始化它的内存是否已在 Python 中释放和重用?
  • 既然您使用的是C++,我可以建议使用string 类型吗?它更不容易出错,您无需担心缓冲区大小和取消分配。当您需要传入(char*) 时,您只需调用string 内置的c_str() 方法即可。
  • _modName 是通过解析 python 脚本的返回字典 _modName = PyString_AsString (PyDict_GetItemString(pValue, (char*)"modName"));
  • 在调用 PyRun_SimpleString() 之前,我是否应该将 PyString_AsString() 返回的内容保存在其他地方?

标签: python c++ embed


【解决方案1】:

感谢 Klamer Schutte 提示正确的方向。 我的代码中的 DECRF 是罪魁祸首。我猜不熟悉参考是如何工作的。 DECREF 调用释放了 pValue 以及 _modName 指向的内容。猜测一个更初学者的问题是,我应该在 _modName 分配之后添加一个 Py_INCREF(pValue) 吗?

_modName = PyString_AsString (PyDict_GetItemString(pValue, (char*)"modName"));
Py_DECREF(pValue);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    相关资源
    最近更新 更多