0

I get message Program received signal SIGSEGV, Segmentation fault when I'm working with my code. My program calls C module with defined struct.

Definition of struct

typedef struct {
    char* str;
    int order;
    int list[10][10];
} Graph;

Definitions of module

static PyMethodDef GraphMethods[] = {
{ "fromString",(PyCFunction)Graph__fromString,METH_VARARGS,"desc" },
{ "order",(PyCFunction)Graph_order,METH_NOARGS,"desc" },
{ NULL }
} ;


static PyTypeObject GraphType = {
PyVarObject_HEAD_INIT( NULL,0 ) // inicjalizacja
"GL.Graph", // nazwa
sizeof( Graph ), // rozmiar
0, //
(destructor)Graph__del__, // destruktor
0,0,0,0,0,0,0,0,0,0, //
(reprfunc)Graph__str__, // obiekt -> napis
0,0,0, //
Py_TPFLAGS_DEFAULT, //
"desc.", // opis
0,0,0,0,0,0, //
GraphMethods, // metody
0,0,0,0,0,0,0, //
(initproc)Graph__init__, // inicjalizator
0, //
(newfunc)Graph__new__ // konstruktor
} ;

Simply, my object gets initialised by function fromString - when I'm using constructor like this:

import GL

g = GL.Graph("A?")
g.order()

(init function)

static int Graph__init__(Graph *self, PyObject *args ) {
    Graph__fromString(self, args);
    printf("ORDER: %d\n", self->order);
    return 0;
}

Program throws error on g.order().

static  PyObject * Graph_order( Graph *self ) {
    int result = self->order;
    return  Py_BuildValue("i", result);
}


PyObject * Graph__fromString(Graph * self, PyObject *args) {
    char * text;
    // Check if user passed the argument
    if (PyArg_ParseTuple(args, "s", &text)) {
        self->str = text;
        int i, k;
        int n = strlen(text);

        /* magic goes here, but im sure this is working */
}
Py_RETURN_NONE;
}

What am I doing wrong? This code worked in plain C, when I moved it to Python, it crashes on every method called after constructor...

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
deem
  • 1,252
  • 1
  • 19
  • 38

1 Answers1

1

Your struct is missing the PyObject_HEAD macro:

typedef struct {
    PyObject_HEAD
    char* str;
    int order;
    int list[10][10];
} Graph;

After expansion this eventually (among other things) also hold a pointer to the type, the fact that you're missing this probably causes this whole thing to blow up.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • And I have a question - does field marked by this macro have to be unique? Field `str` is debugging variable for me, but when I add this macro to another, it does not work. I would like to make `list` annotated by this macro? – deem Nov 27 '16 at 11:07
  • I'm not sure I'm understanding your question, what do you mean unique? – Dimitris Fasarakis Hilliard Nov 27 '16 at 11:13
  • I am asking if I can use this macro on any field in struct or this field should be unique for every graph? – deem Nov 27 '16 at 11:30
  • This macro isn't applied on a field of the struct @deem. It *adds a field* to the struct (specifically an `PyObject ob_base;` field if `PyObject_HEAD` is used and `PyVarObject ob_base` if `PyObject_VAR_HEAD` is used). – Dimitris Fasarakis Hilliard Nov 27 '16 at 11:33
  • Take a look on the [docs on extending Python](https://docs.python.org/3/extending/extending.html), it has most of this information – Dimitris Fasarakis Hilliard Nov 27 '16 at 11:34