0

For me, the following all result in a segfault:

my_array->descr->subarray->shape;
my_array->dimensions;
PyArray_SHAPE(my_array);
PyArray_DIMS(my_array);
PyArray_ITEMSIZE(my_array);
PyArray_NBYTES(my_array);

My function looks like this:

static PyObject* exterior(PyObject* self, PyArrayObject* old_simplices_array)
{//code here

The rest of my cpp file looks like this:

#include "Python.h"
#include "numpy/arrayobject.h"

/* function */

static PyMethodDef compiled_methods[] = 
{
    {"_exterior",(PyCFunction)exterior , METH_VARARGS},
    {NULL,      NULL}        /* Sentinel */
};

PyMODINIT_FUNC init_alto(void)
{
    (void) Py_InitModule("_alto", compiled_methods);
    import_array();
}

The python code that passes the array to "exterior" just passes an NxM uint array. That part works. I can access the array's strides and data. I just cannot determine the bounds of iteration. I am working from within sage if that makes any difference.

How am I supposed to iterate over an array without segfaulting? If the answer is obvious, please idiotproof your answer.

For a better idea of what the function looks like, see here.

Community
  • 1
  • 1
Alex Eftimiades
  • 2,527
  • 3
  • 24
  • 33

1 Answers1

2

In the past I have done the following to iterate over a PyArrayObject:

static PyObject *func1(PyObject *self, PyObject *args) {
    PyArrayObject *X;
    int ndX;
    npy_intp *shapeX;
    PyArray_Descr *dtype;
    NpyIter *iter;
    NpyIter_IterNextFunc *iternext;

    PyArg_ParseTuple(args, "O!", &PyArray_Type, &X);
    ndX = PyArray_NDIM(X);
    shapeX = PyArray_SHAPE(X);
    dtype = PyArray_DescrFromType(NPY_DOUBLE);

    iter = NpyIter_New(X, NPY_ITER_READONLY, NPY_KEEPORDER, NPY_NO_CASTING, dtype);
    if (iter==NULL) {
        return NULL;
    }
    iternext = NpyIter_GetIterNext(iter, NULL);
    dataptr = (double **) NpyIter_GetDataPtrArray(iter);

    do {
        cout << **dataptr << endl;
    } while (iternext(iter));

    NpyIter_Deallocate(iter);
    return Py_BuildValue(something);
}

To find out more information check out this link: http://docs.scipy.org/doc/numpy/reference/c-api.iterator.html

Joel Vroom
  • 1,611
  • 1
  • 16
  • 30
  • 1
    I thought your example was working, but I was just getting a NULL iter. Are you sure you do not have to do anything special to the array that python passes to C? – Alex Eftimiades Sep 13 '13 at 18:34
  • I edited the above to show how X is parsed. This works for me. PyArg_ParseTuple(args, "O!", &PyArray_Type, &X); – Joel Vroom Sep 13 '13 at 19:15