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