Numpy C++程序总是给出段错误(很可能是语法或类型的误用)
Numpy C++ program always gives segfault (most likely misuse of syntax or types)
我正在为python程序开发我的第一个C++扩展。我一直在尝试调试这段特定的代码几个小时,但我没有想法。
段错误似乎与传递给C++代码的PyArrayObject
old_simplices_array
有关。该对象是类型 uint32
的2d numpy array
。
此代码直接从scipy.weave
组合的内容修改而来。 当代码被格式化并由scipy.weave.inline使用时,一切正常。这似乎消除了我的程序的python部分和算法本身可能是罪魁祸首。
这只剩下语法和类型。有没有人看到任何不正确的语法或类型转换代码?
static PyObject* exterior(PyObject* self,
PyArrayObject* old_simplices_array)
{
const short unsigned int step = old_simplices_array->dimensions[1];
const short unsigned int j_max = step - 1;
const long unsigned int col_max =
old_simplices_array->dimensions[0] * step;
short unsigned int j, k, face_index;
long unsigned int col;
unsigned int num_simplices = 0;
PyObject* indices = PyList_New(0);
PyObject* indptr = PyList_New(0);
PyObject* data = PyList_New(0);
PyObject* simplices = PyList_New(0);
PyList_Append(indptr, PyLong_FromLong(0));
PyObject* simplex_to_index = PyDict_New();
for(col = 0; col < col_max; col+=step)
{
for(j = 0; j <= j_max; j++)
{
face_index = 0;
PyObject* face = PyTuple_New(j_max);
for(k = 0; k <= j_max; k++)
{
if(j != k)
{
PyTuple_SetItem(face, face_index,
PyLong_FromLong(old_simplices_array->data[col + k]));
face_index++;
}
}
if(PyDict_Contains(simplex_to_index, face))
{
PyList_Append(indices,
PyDict_GetItem(simplex_to_index, face));
}
else
{
PyDict_SetItem(simplex_to_index, face,
PyLong_FromLong(num_simplices));
PyList_Append(simplices, face);
num_simplices++;
}
PyList_Append(data, PyLong_FromLong(1 - 2 * (j % 2)));
}
PyList_Append(indptr, PyLong_FromLong(col + j));
}
return PyTuple_Pack(3, PyTuple_Pack(3, data, indices, indptr), simplices,
simplex_to_index);
}
------更新------
GDB 表示
const short unsigned int step = old_simplices_array->dimensions[1];
导致段错误。我是否滥用了类型?
------更新------
尽管GDB告诉我,
const short unsigned int step = old_simplices_array->dimensions[1];
导致段错误,如果我在 for 循环之前从程序返回,我没有得到任何段错误(只是 python 端抱怨返回 NoneType 的错误)。
这是完整的回溯:
Program received signal SIGSEGV, Segmentation fault.
exterior (self=<optimized out>, old_simplices_array=0xec0a50)
at src/_alto.cpp:39
warning: Source file is more recent than executable.
39 const short unsigned int step = old_simplices_array->dimensions[1];
(gdb) bt
exterior (self=<optimized out>, old_simplices_array=0xec0a50)
at src/_alto.cpp:39
0x00007ffff7aedad2 in PyEval_EvalFrameEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aeddc9 in PyEval_EvalFrameEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aee902 in PyEval_EvalCodeEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a70ad6 in ?? ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e in PyObject_Call ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a53b80 in ?? ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e in PyObject_Call ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aaaea0 in ?? ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aa68bc in ?? ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e in PyObject_Call ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7ae9bce in PyEval_EvalFrameEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aee902 in PyEval_EvalCodeEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aeea32 in PyEval_EvalCode ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b103fa in PyRun_FileExFlags ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b10e3d in PyRun_SimpleFileExFlags ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b26972 in Py_Main ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff6d29ea5 in __libc_start_main ()
from /lib/x86_64-linux-gnu/libc.so.6
0x00000000004006d1 in _start ()
一般来说,C模块中方法的签名是PyObject* f(PyObject* self, PyObject* args)
的,其中args
旨在通过PyArg_ParseTuple
解析。 您可以在scipy.weave
生成的代码中看到这一点:http://docs.scipy.org/doc/scipy/reference/tutorial/weave.html#a-quick-look-at-the-code)。 除非有你尚未发布的一些包装函数为你调用PyArg_ParseTuple
,否则你的exterior
方法必须调用它才能从泛型PyObject* args
中提取PyArrayObject
。
- 很好的语法来获取对向量/数组数据的大小引用?
- Opengl问题:很可能是简单的纹理问题
- 放置/分段语法是否可能出现懒惰"operator or"重载?
- 为许多类可能需要的所有常量变量制作独立的头文件是否是一种很好的做法?
- 在关闭应用程序期间正确关闭线程,该线程可能会运行很长时间的循环
- 使用 stl 迭代器封装向量是否很好?如果是?怎么可能呢?
- 访问未初始化的值,很可能在向量中
- 多态性抽象语法树(递归下降解析器):不可能
- 为什么这个C++代码可以工作?(可能很简单)
- 在C 11 /14语法中,是否有可能编写lambda函数,该函数将看到父变量
- 使用自定义对象的地图使用MAP?可能是语法问题
- 打印所有可能的组合,包括重复,顺序也很重要
- C++ 不合逻辑 >= 处理 vector.size() 时的比较很可能是由于size_type是无符号的
- 简而言之,我真的很纠结语法,有人可以帮助我解决这个问题
- Numpy C++程序总是给出段错误(很可能是语法或类型的误用)
- 预期的不合格id错误,很可能是原因
- "Undefined symbols for Architecture x86_64 "未使用模板,可能存在语法错误
- 对列表中最有可能由列表顶部的人说出的积极单词和列表末尾很少说出的单词进行排序
- BST上的"unresolved external symbol public: __thiscall",很可能是由于模板
- 关于C++中的分段错误的问题很可能是由自定义复制构造函数引起的