Python C 扩展 - 错误 `python3.6' : free(): invalid pointer: 0x

标签 python c python-c-extension

我一直在学习如何用 C 扩展 Python,我终于让它以某种方式工作,但我遇到了这个非常奇怪的错误。我制作了一个具有单一功能的测试模块来测试数字是否为素数。这是代码:

cmodule.c

#include <stdbool.h>
#include <math.h>
#include <Python.h>

bool isprime(int n) {
    if (n == 0 || n == 1)
        return false;

    for (int i = 2; i < (int)sqrt(n) + 1; i++) {
            if (n % i == 0)
                    return false;
    }
    return true;
}

static PyObject * isprime_wrapper(PyObject * self, PyObject * args) {
    int n;
    if (!PyArg_ParseTuple(args, "i", &n))
        return NULL;

    bool retval = isprime(n);
    if (retval)
        return Py_True;
    else
        return Py_False;    
}

static PyMethodDef methods[] = {
    {"isprime", isprime_wrapper, METH_VARARGS, "Tests if a number is prime."},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef cmodule = {
    PyModuleDef_HEAD_INIT,
    "cmodule",
    "Test module.",
    -1,
    methods
};

PyMODINIT_FUNC PyInit_cmodule(void) {
    return PyModule_Create(&cmodule);
}

setup.py

from distutils.core import setup, Extension

cmodule = Extension("cmodule", sources = ["cmodule.c"])

setup(name = "CModuleTest",
    ext_modules = [cmodule])

乍一看它工作正常。我运行 python3.6 setup.py build 并且构建没有错误,我可以进入包含 .so 文件的目录,启动 Python session ,然后调用 cmodule.isprime() 正常.然而,奇怪的是当我在循环中使用代码时,出现了这个错误:

>>> import cmodule
>>> for i in range(1, 1000001):
...     n = cmodule.isprime(i)
... 
*** Error in `python3.6': free(): invalid pointer: 0x0000561cc1faf620 ***

如果有人觉得有帮助,我可以添加完整的回溯。我在执行此操作时打印出 i 的所有值,并且在尝试运行 isprime(154) 时似乎总是出现此错误。但是,当我在终端中打开 Python 并尝试单独运行 isprime(154) 或任何其他数字时,它工作正常。我唯一一次能够复制它是在循环中,我不知道它可能来自哪里。我看过其他有类似问题的人,这似乎源于他们在 C 代码中不正确地使用 free(),但我从不从我的代码中调用 free()。有谁知道是什么原因造成的?感谢您的帮助。

最佳答案

CPython 对象被引用计数,返回 Py_True 和 Py_False 可能是问题所在。请改用 Py_RETURN_TRUE 等。它们适本地增加引用计数并返回它们各自的单例对象。

关于Python C 扩展 - 错误 `python3.6' : free(): invalid pointer: 0x,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42617485/

相关文章:

python - 在 Python 中查找目录中的特定路径

python - SQLalchemy 中带有子查询、分组依据、计数和求和函数的高级 SQL 查询

c - 延迟写入错误

Python 3 兼容性问题

python - 如何在运行时复制 python 模块?

python - 如何彻底清理python中的一串非法字符?

python - 字典迭代 Python

c - "strlen"在 C 中给出不同的结果

c - 提前退出递归函数时返回什么?

python - 如何检查 PyObject 是 Python C 扩展的字符串还是 Unicode