【问题标题】:Wrapping C with Python; free(char *) invalid pointer用 Python 包装 C; free(char *) 无效指针
【发布时间】:2014-04-21 19:27:03
【问题描述】:

我正在关注this 使用 Python 封装 C/C++ 的教程。我已经逐字复制了示例代码,但仍会在下面列出。

你好.c

#include <stdio.h>
#include <Python.h>

// Original C Function
char * hello(char * what)
{
    printf("Hello %s!\n", what);
    return what;
}

//  1) Wrapper Function that returns Python stuff
static PyObject * hello_wrapper(PyObject * self, PyObject * args) 
{
  char * input;
  char * result;
  PyObject * ret;

  // parse arguments
  if (!PyArg_ParseTuple(args, "s", &input)) {
    return NULL;
  }

  // run the actual function
  result = hello(input);

  // build the resulting string into a Python object.
  ret = PyString_FromString(result);

  free(result);

  return ret;
}

脚本hello.c 定义了一个简单的“hello”函数,以及一个返回 Python 对象的包装器,并且(假设地)释放 c char * 指针。 这是代码因运行时错误而失败的地方: Error in '/usr/bin/python': free(): invalid pointer: 0x00000000011fbd44。虽然我认为错误应该限制在这个范围内,但让我们检查一下包装器的其余部分以防万一......

hello.c 包含在模块的定义中,它允许在 Python 中调用其方法。模块定义如下:

hellomodule.c

#include "hello.c"
#include <Python.h>

// 2) Python module
static PyMethodDef HelloMethods[] =
{
        { "hello", hello_wrapper, METH_VARARGS, "Say hello" },
        { NULL, NULL, 0, NULL }
};

// 3) Module init function
DL_EXPORT(void) inithello(void)
{
    Py_InitModule("hello", HelloMethods);
}

最后,实现了一个 Python 脚本来构建模块:

setup.py

#!/usr/bin/python
from distutils.core import setup, Extension

# the c++ extension module
extension_mod = Extension("hello", ["hellomodule.c"]) #, "hello.c"])

setup(name = "hello", ext_modules=[extension_mod])

一旦setup.py 运行,该模块就可以被导入到任何Python 脚本中,并且它的成员函数应该是可以访问的,并且已经被证明是可以访问的,但无效指针错误除外。我花了很多时间在这方面无济于事。请帮忙。

【问题讨论】:

    标签: python c malloc wrapper free


    【解决方案1】:

    根据the documentationPyArg_ParseTuple()产生的指针不应该被释放:

    此外,您不必自己释放任何内存,除了 es、es#、et 和 et# 格式。

    消除free(result); 调用应该会停止崩溃。

    【讨论】:

    • 如果我错了,请纠正我,但不是input是由PyArg_ParseTuple()而不是result生成的吗?在更改hello(char * what) 函数以返回除输入之外的一些字符串(让我们使用“Bears”)之后,我认为应该解决问题,但它只是将错误更改为分段错误,当我仍然发生时免费(结果)。
    • 这取决于您如何在hello() 函数中生成该字符串。仅当您 malloc()ed 时,它才应该是 free()d。
    • 是的,你是对的。如果返回字符串为malloc()ed,则必须为free()d。谢谢你帮助我!
    猜你喜欢
    • 2015-03-31
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多