C-API: A beginner's problem

Georg Brandl g.brandl-nospam at gmx.net
Sun Mar 19 18:10:24 EST 2006


Fabian Steiner wrote:
> I recently started learning C since I want to be able to write Python 
> extension modules. In fact, there is no need for it, but I simply want 
> to try something new ...
> 
> I tried to implement the bubblesort algorithm in C and to use it in 
> python; bubblesort.c compiles fine, but whenever I want to import the 
> modul and call the function I get a segmentation fault. This is what the 
> code looks like:
> 
> static PyObject *py_bubblesort(PyObject *self, PyObject *args) {
> 	PyObject *seq = NULL, *item, *newseq = NULL;
> 	int seqlen, i;

        long it;

> 	if(!PyArg_ParseTuple(args, "O", &seq)) {
> 		return NULL;
> 	}
> 	seq = PySequence_Fast(seq, "argument must be iterable");
> 	if(!seq) {
> 		return NULL;
> 	}
> 	seqlen = PySequence_Fast_GET_SIZE(seq);
> 	int list[seqlen];
> 	for (i = 0; i <= seqlen; i++) {

That is one iteration too much. Use

        for (i = 0; i < seglen; i++)

> 		item = PySequence_Fast_GET_ITEM(seq, i);

Now item is a PyObject*. You'll have to convert it to an integer now:

                it = PyInt_AsLong(item);
                if (it == -1 && PyErr_Occurred()) {
                    Py_DECREF(seq);
                    /* set a new exception here if you like */
                    return NULL;
                }

> 		list[i] = it;
> 	}
> 	bubblesort(list, seqlen);
> 	newseq = PyList_New(seqlen);
> 	if(!newseq) {

Do not forget to DECREF seq:
                Py_DECREF(seq);

> 		return NULL;
> 	}
> 	for(i = 0; i < seqlen; i++) {
> 		PyList_SetItem(newseq, i, list[i]);

List items must be PyObject*s, not plain ints. Use:
                PyList_SetItem(newseq, i, PyInt_FromLong(list[i]));
(This is sloppy error checking, but if PyInt_FromLong fails you're out of
memory anyways ;)

> 	}

Again, seq is not needed anymore:
        Py_DECREF(seq);

> 	return newseq;
> 
> bubblesort(int list[], int seqlen) is doing the actual job and it is 
> working.
> 
> What did I do wrong? As I am quite new to C, I probably made many 
> mistakes, so please feel free to correct me.

There's quite a bit you can overlook, especially stale references to PyObjects.
I'm not even sure the code compiles or runs correctly with my corrections ;)

Cheers,
Georg



More information about the Python-list mailing list