1

How can I perform the equivalent of the following C++ code in Cython?

typedef vector<double> dvec;
dvec *arr = new dvec[n]; // n is an unsigned int (unknown at compile time)

// do something with arr; for example...
arr[0].push_back(10);
cout << arr[0][0] << endl;

I've tried to malloc the memory for the n vectors, but then I do not know how to do a placement new in Cython. Any help would be greatly appreciated.

4
  • I don't understand what you're asking here. Placement new is something like double *d = new(arr[0]) double, where you construct a new double in an already-allocated memory location. You're not doing that in your code, and I can't imagine what use it would have in or near this code. Commented Jun 24, 2018 at 1:25
  • I'm trying to translate this code into Cython. I do not know how. I was suggesting a combination of malloc and placement new as a possibility (but I don't think there's a placement new in Cython). Commented Jun 24, 2018 at 1:46
  • 2
    How about a vector of vectors? Unless this is something you could do with Python classes instead. Commented Jun 24, 2018 at 7:08
  • @DavidW: +1. Yeah, I ended up giving up and implementing it with vector[vector[double]], but I was just curious as to if it was possible to do it this way. Commented Jun 24, 2018 at 12:17

2 Answers 2

6

It doesn't seem like you can do array new (new something[n]) in Cython. The simplest solution would be to create 1-line C++ function to do array new and array delete, and call those instead.

template <typename T>
T* array_new(int n) {
    return new T[n];
}

template <typename T>
void array_delete(T* x) {
    delete [] x;
}

Called from the following Cython file

# distutils: language = c++

from libcpp.vector cimport vector

ctypedef vector[double] dvec

cdef extern from "cpp_funcs.hpp":
    T* array_new[T](int)
    void array_delete[T](T* x)

def example(int n):
    cdef dvec* arr = array_new[dvec](n)
    try:
        if n>0:
            arr[0].push_back(10)
            print(arr[0][0])
    finally:
        array_delete(arr)

Given that Cython's C++ support is limited, and awkward in places (and given that you have to have a pretty good understanding of C++ to use it anyway) I think that writing a small amount of C++ code is usually a reasonable solution, and can save quite a bit of time. Some people seem to want to avoid this at all costs though....


I'd still recommend using a vector of vectors (vector<vector<double>>) instead since you get the memory management for free. Even better would be to stick with Python types and use a list of numpy arrays, but that might not be suitable if you want to interface with external C++ code.

Sign up to request clarification or add additional context in comments.

Comments

3

As an addition to @DavidW's answer: Since Cython 0.28 there is a new feature which allows verbatim C-code. Its advantage is a seamless usage of such small C/C++-wrappers:

cdef extern from *:
    """
    template <typename T>
    T* array_new(int n) {
        return new T[n];
    }

    template <typename T>
    void array_delete(T* x) {
        delete [] x;
    }
    """
    T* array_new[T](int)
    void array_delete[T](T* x)

from libcpp.vector cimport vector
.... and so on

without the need for creating an extern header-file.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.