Cython interfaced with C++: segmetation fault for large arrays : I am transferring my code from Python/C interfaced using ctypes to Python/C++ interfaced using Cython. The new interface will give me an easier to maintain code, because I can exploit all the C++ features and need relatively few lines of interface-code. 

The interfaced code works perfectly with small arrays. However it encounters a *segmentation fault* when using large arrays. I have been wrapping my head around this problem, but have not gotten any closer to a solution. I have included a minimal example in which the segmentation fault occurs. Please note that it consistently occurs on Linux and Mac, and also valgrind did not give insights. Also note that the exact same example in pure C++ does work without problems.

The example contains a Sparse matrix class (of the compressed row format) in C++. An interface is created in Cython. As a result the class can be used from Python. 

# C++ side

``sparse.h``

    #ifndef SPARSE_H
    #define SPARSE_H

    #include <iostream>
    #include <cstdio>

    using namespace std;

    class Sparse {

      public:
        double* data;
        int*    row_ptr;
        int*    col_ind;
        int*    shape;
        int     nnz;

        Sparse();
        ~Sparse();
        Sparse(int* shape, int nnz, double* data, int* row_ptr, int* col_ind);
        void view(void);

    };

    #endif

``sparse.cpp``


    #include "sparse.h"

    // =============================================================================

    Sparse::Sparse()
    {
      data    = NULL;
      row_ptr = NULL;
      col_ind = NULL;
      shape   = NULL;
      nnz     = 0   ;
    }

    // =============================================================================

    Sparse::~Sparse() {}

    // =============================================================================

    Sparse::Sparse(int* Shape, int NNZ, double* Data, int* Row_ptr, int* Col_ind)
    {

      shape   = Shape  ;
      nnz     = NNZ    ;
      data    = Data   ;
      row_ptr = Row_ptr;
      col_ind = Col_ind;

    }

    // =============================================================================

    void Sparse::view(void)
    {

      if ( row_ptr==NULL || col_ind==NULL || data==NULL || shape==NULL ) {
        cout << "NULL-pointer found" << endl;
        return;
      }

      int i,j;

      for ( i=0 ; i<shape[0] ; i++ )
        for ( j=row_ptr[i] ; j<row_ptr[i+1] ; j++ )
          printf("(%3d,%3d) %4.1f\n",i,col_ind[j],data[j]);

    }

    // =============================================================================

# Cython interface

``csparse.pyx``


    import  numpy as np
    cimport numpy as np

    # ==============================================================================

    cdef extern from "sparse.h":
      cdef cppclass Sparse:
        Sparse(int*, int, double*, int*, int*) except +
        double* data
        int*    row_ptr
        int*    col_ind
        int*    shape
        int     nnz
        void    view()

    # ==============================================================================

    cdef class PySparse:

      # ----------------------------------------------------------------------------

      cdef Sparse *ptr

      # ----------------------------------------------------------------------------

      def __init__(self,**kwargs):
        pass

      def __cinit__(self,**kwargs):

        cdef np.ndarray[np.int32_t  , ndim=1, mode="c"] shape, col_ind, row_ptr
        cdef np.ndarray[np.float64_t, ndim=1, mode="c"] data

        shape    = np.array(kwargs['shape'  ],dtype='int32'    )
        data     =          kwargs['data'   ].astype(np.float64)
        row_ptr  =          kwargs['row_ptr'].astype(np.int32  )
        col_ind  =          kwargs['col_ind'].astype(np.int32  )

        self.ptr = new Sparse(
          <int*>    shape.data   if shape   is not None else NULL,
          data.shape[0],
          <double*> data   .data if data    is not None else NULL,
          <int*>    row_ptr.data if row_ptr is not None else NULL,
          <int*>    col_ind.data if col_ind is not None else NULL,
        )

      # ----------------------------------------------------------------------------

      def __dealloc__(self):
        del self.ptr

      # ----------------------------------------------------------------------------

      def view(self):
        self.ptr.view()

      # ----------------------------------------------------------------------------

``setup.py``

    from distutils.core import setup, Extension
    from Cython.Build   import cythonize

    setup(ext_modules = cythonize(Extension(
      "csparse",
      sources=["csparse.pyx", "sparse.cpp"],
      language="c++",
    )))

# Python side


    import numpy as np
    import csparse

    N = 5000

    matrix = csparse.PySparse(
      shape   = np.array([N,N],dtype='int32'),
      data    = np.random.rand(N*N),
      row_ptr = np.arange(0,N*N+1,N  ,dtype='int32'),
      col_ind = np.tile(np.arange(0,N,dtype='int32'),N),
    )

    matrix.view() # --> segmentation fault

