2

I am writing a code, trying to get used to the C API of NumPy arrays.

#include <Python.h>
#include "numpy/arrayobject.h"
#include <stdio.h>
#include <stdbool.h>


static char doc[] =
"Document";

static PyArrayObject *
    trace(PyObject *self, PyObject *args){

    PyArrayObject *matin;

    if (!PyArg_ParseTuple(args, "O!",&PyArray_Type, &matin))
         return NULL;

    printf("a");
    return matin;
}

static PyMethodDef TraceMethods[] = {
    {"trace", trace, METH_VARARGS, doc},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inittrace(void)
{
    (void) Py_InitModule("trace", TraceMethods);
    import_array();
}

This is a stripped-down version. I just want to be able to get an object of type PyArrayObject and return it back. Unfortunately this gives a SegFault also.

Linux, 64-bit, Python 2.7.1

Translunar
  • 3,739
  • 33
  • 55
mehmet.ali.anil
  • 505
  • 6
  • 17

1 Answers1

1

From the docs:

O (object) [PyObject *]
Store a Python object (without any conversion) in a C object pointer. The C program thus receives the actual object that was passed. The object’s reference count is not increased. The pointer stored is not NULL.

O! (object) [typeobject, PyObject *]
Store a Python object in a C object pointer. This is similar to O, but...

You're returning a stolen reference. Increment it first.

Community
  • 1
  • 1
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • I'm not familiar with software architecture with C, but I guess when I don't increment the reference with `PYINCREF(the_python_object);` then the garbage collector spots that its reference is 0, and frees that memory. (correct me if I am wrong) – mehmet.ali.anil Oct 14 '11 at 19:57
  • Essentially yes, but it's the refcount dropping to 0 that invokes the GC rather than the other way around. – Ignacio Vazquez-Abrams Oct 14 '11 at 21:53