Python C 扩展 - `python3.6' 中的错误:free():无效指针:0x
Python C Extension - Error in `python3.6': free(): invalid pointer: 0x
我一直在学习如何用 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 会话,然后调用 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 并单独尝试 运行ning isprime(154) 或任何其他数字时,它工作正常。我唯一一次能够复制它是在循环中,我不知道它可能来自哪里。我看过其他有类似问题的人,这似乎源于他们在 C 代码中不正确地使用 free(),但我从不从我的代码中调用 free()。有谁知道是什么原因造成的?感谢您的帮助。
CPython 对象被引用计数,returning Py_True 和 Py_False 可能是问题所在。请改用 Py_RETURN_TRUE 等。它们适当地增加了它们各自的单例对象的引用计数和 return。
我一直在学习如何用 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 会话,然后调用 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 并单独尝试 运行ning isprime(154) 或任何其他数字时,它工作正常。我唯一一次能够复制它是在循环中,我不知道它可能来自哪里。我看过其他有类似问题的人,这似乎源于他们在 C 代码中不正确地使用 free(),但我从不从我的代码中调用 free()。有谁知道是什么原因造成的?感谢您的帮助。
CPython 对象被引用计数,returning Py_True 和 Py_False 可能是问题所在。请改用 Py_RETURN_TRUE 等。它们适当地增加了它们各自的单例对象的引用计数和 return。