Numpy,在 C++ 段错误中创建一维数组

Posted

技术标签:

【中文标题】Numpy,在 C++ 段错误中创建一维数组【英文标题】:Numpy, creating 1D array in C++ segfaults 【发布时间】:2017-03-14 12:32:27 【问题描述】:

我正在尝试在 C++ 中为 numpy 创建一维数组:

PyObject* foo()

   npy_intp length[1];
   length[0] = 10;
   PyObject* my_array = PyArray_SimpleNew(1, length, NPY_DOUBLE);
   return boost::python::incref(my_array);

然后我做一个python模块:

BOOST_PYTHON_MODULE(pyMod)

    using namespace boost::python;

    import_array();

    def("foo", foo);

当我在 python 中运行它时,调用 foo(),它在执行对 PyArray_SimpleNew 的调用时会出现段错误,即使我已经调用了 import_array,这似乎是导致这种段错误的常见原因。如果我制作一个维度为 [10, 1] 的二维数组,则效果很好,即:

PyObject* foo()

   npy_intp length[2] = 10, 1;
   PyObject* my_array = PyArray_SimpleNew(2, length, NPY_DOUBLE);
   return boost::python::incref(my_array);

在python中是这样使用的

import numpy as np
import pyMod

if __name__ == "__main__":
    v = pyMod.foo()

对为什么会出现此段错误有任何想法吗?

【问题讨论】:

在哪一行出现段错误?请提供带有详细错误消息的minimal reproducible example(只是一个函数;向我们展示你如何调用它) 调用 PyArray_SimpleNew 时出现段错误 我的评论不仅仅是第一句话。 【参考方案1】:

我不确定您是如何将 PyObject* 暴露给 Python,但我认为正确的方法是通过 boost::python::object 暴露它。

另一点是您正在使用 PyObject 调用 boost::python::object。尽管有可能,但不建议这样做(参见 David Abrahams 撰写的 guidelines)。所以应该使用 boost::python::handle 来解决这种情况。

boost::python::object foo()

   npy_intp dims[1] = 10;
   PyObject* p_array = PyArray_SimpleNew(boost::size(dims), dims, NPY_FLOAT);
   boost::python::handle<> handle(boost::python::borrowed(p_array));
   return boost::python::object(handle);

【讨论】:

不要认为这是问题所在,因为它在返回之前会崩溃并适用于 2D 数组。不过谢谢你的回答。 仅仅因为它使用二维数组并不意味着它是正确的。我已经编辑了答案,提供了一个解释句柄重要性的链接。 但是我需要一个来自 boost::python::object 的转换器,它只返回 incref(boost_py_obj->ptr()): PyObject* convert(boost::python::object obj) 返回 boost::python::incref(obj->ptr)); ? 我已将问题编辑为不使用 boost::python::object,然后我不需要句柄,因为我没有通过 boost::python::object?

以上是关于Numpy,在 C++ 段错误中创建一维数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中创建索引从 1 开始的一维数组

numpy中的ndarray方法和属性

对数值计算numpy的一些总结,感兴趣的朋友可以看看

使用网格数据和一维纹理图在 opengl 中创建等高线图

python数据分析模块:numpy、pandas全解

将 NumPy 数组的第一维解压缩到 pyplot.plot