Python C-API:PYDICT_GETITEM上的分割故障,可能的参考问题
Python C-API: segmentation fault on PyDict_GetItem, possible reference problem?
i在C中有一个引用词典列表。我正在编写一个函数来计算列表的两个成员之间的点产品:
PyObject *handle; // reference to a list of dictionaries
virtual float dot_product () (unsigned i, unsigned j) const {
// dot product of handle[i] and handle[j]
PyObject *a = (PyObject*)PyList_GetItem(handle, (Py_ssize_t)i);
PyObject *b = (PyObject*)PyList_GetItem(handle, (Py_ssize_t)j);
PyObject *key, *a_value;
Py_ssize_t pos = 0;
double dot_product = 0;
while (PyDict_Next(a, &pos, &key, &a_value)) {
PyObject* b_value = PyDict_GetItem(b, key);
if (b_value != NULL){
dot_product += PyFloat_AsDouble(a_value) * PyFloat_AsDouble(b_value);
}
}
return dot_product;
}
这会导致分割故障。使用GDB进行调试,看来分割故障是由PYDICT_GETITEM(B,KEY)引起的。这让我怀疑我的参考数数有问题。
阅读了参考计数的文档后,似乎借了上述代码中的所有参考文献,因此我认为无需使用py_incref或py_decref ...但是我很容易错。我需要使用py_incref或py_decref中的上述代码中有一个位置吗?
编辑:我应该注意,我已经进行了检查以确保A和B不是零,并且还可以确保我和J不超过列表的大小。我在问题中从代码中删除了这些检查,以使其更简单。 -
检查您的返回值。如果i
和j
分别超过handle
引用的list
的长度,则a
和b
均可为NULL
。PyDict_GetItem
假设 dict
传递的不是NULL
指针,而是在不确认该假设的情况下将其删除,这将导致立即的segfault。
您的主要问题是确定如何报告错误。C 例外将适用于C ,但是除非您抓住并将其转换为Python级别异常,否则Python不会理解它。无论如何,在您弄清楚这一点之前,返回NaN
表示失败:
#include <cmath>
PyObject *handle; // reference to a list of dictionaries
virtual float dot_product () (unsigned i, unsigned j) const {
// dot product of handle[i] and handle[j]
PyObject *key, *a_value;
Py_ssize_t pos = 0;
double dot_product = 0;
// Check both indices are valid
PyObject *a = (PyObject*)PyList_GetItem(handle, (Py_ssize_t)i);
if (!a) return NAN;
PyObject *b = (PyObject*)PyList_GetItem(handle, (Py_ssize_t)j);
if (!b) return NAN;
// Test if you actually got dicts
if (!PyDict_Check(a) || !PyDict_Check(b)) return NAN;
while (PyDict_Next(a, &pos, &key, &a_value)) {
PyObject* b_value = PyDict_GetItem(b, key);
if (b_value != NULL){
// Check that both values are really Python floats and extract C double
double a_val = PyFloat_AsDouble(a_value);
if (a_val == -1.0 && PyErr_Occurred()) return NAN;
double b_val = PyFloat_AsDouble(b_value);
if (b_val == -1.0 && PyErr_Occurred()) return NAN;
dot_product += a_val * b_val;
}
}
return dot_product;
}
相关文章:
- 警告处理为错误这里有什么问题
- 分段故障(堆芯转储)矢量
- 最小硬币更换问题(自上而下方法)
- 分段故障背包问题
- 分割故障 - 遇到问题,创建新的数组实例
- C :分割故障(核心倾倒)问题
- 为什么最后一个拆分函数会导致分割故障?如何解决此问题
- AIX:未知分段故障问题
- Python C-API:PYDICT_GETITEM上的分割故障,可能的参考问题
- 使用指针和结构C 计算两个点之间的距离,分割故障问题
- SSE _mm_store_ps分段故障问题
- 细分故障问题
- R内部分段故障和链接问题
- 分段故障和指针问题
- 创建二进制搜索树时出现分段故障问题
- 递归呼叫分段故障问题
- 使用arm-linux- gnuabi -g++ -o时出现段故障,不使用-o也不会出现问题
- "Ambiguous Overload"回路中的问题和故障 CIN
- 单链表段故障问题
- 在c++和Linux中查找总线错误/Seg故障的问题