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;
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++) {
item = PySequence_Fast_GET_ITEM(seq, i);
list[i] = item;
}
bubblesort(list, seqlen);
newseq = PyList_New(seqlen);
if(!newseq) {
return NULL;
}
for(i = 0; i < seqlen; i++) {
PyList_SetItem(newseq, i, list[i]);
}
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.
Cheers,
Fabian 10 1481
Fabian Steiner wrote: What did I do wrong? As I am quite new to C, I probably made many mistakes, so please feel free to correct me.
The following line:
for (i = 0; i <= seqlen; i++) {
Should be "for (i = 0; i < seqlen; i++) {". Otherwise the last
assignment will be out of bounds and probably corrupts heap.
Heikki Salo wrote: Fabian Steiner wrote: What did I do wrong? As I am quite new to C, I probably made many mistakes, so please feel free to correct me.
The following line:
> for (i = 0; i <= seqlen; i++) {
Should be "for (i = 0; i < seqlen; i++) {". Otherwise the last assignment will be out of bounds and probably corrupts heap.
And closer look tells that the code should not even compile. Is the code
cut & pasted directly? Line "list[i] = item;" tries to assign a pointer
to an int-array, which should not compile. There are other similar oddities.
Heikki Salo wrote: And closer look tells that the code should not even compile. Is the code cut & pasted directly? Line "list[i] = item;" tries to assign a pointer to an int-array, which should not compile. There are other similar oddities.
.... such as the declaration of list at a point in the code which is not
permitted in C, and using a non constant value for the length (which is
also not allowed).
Duncan Booth wrote: Heikki Salo wrote:
And closer look tells that the code should not even compile. Is the code cut & pasted directly? Line "list[i] = item;" tries to assign a pointer to an int-array, which should not compile. There are other similar oddities.
... such as the declaration of list at a point in the code which is not permitted in C, and using a non constant value for the length (which is also not allowed).
They are allowed in C99, according to GCC's manual.
Nick Smallbone wrote: Duncan Booth wrote: Heikki Salo wrote:
> > And closer look tells that the code should not even compile. Is the > code cut & pasted directly? Line "list[i] = item;" tries to assign a > pointer to an int-array, which should not compile. There are other > similar oddities.
... such as the declaration of list at a point in the code which is not permitted in C, and using a non constant value for the length (which is also not allowed).
They are allowed in C99, according to GCC's manual.
Which just shows how long it is since I wrote any C.
Heikki Salo wrote: Heikki Salo wrote: Fabian Steiner wrote: What did I do wrong? As I am quite new to C, I probably made many mistakes, so please feel free to correct me.
The following line:
> for (i = 0; i <= seqlen; i++) {
Should be "for (i = 0; i < seqlen; i++) {". Otherwise the last assignment will be out of bounds and probably corrupts heap.
And closer look tells that the code should not even compile. Is the code cut & pasted directly? Line "list[i] = item;" tries to assign a pointer to an int-array, which should not compile. There are other similar oddities.
Okay, thank you (and the others) for these hints. As you see, I am quite
new to C and I just wrote these lines by using parts I have found in the
newsgroup. Unfortunately, the Python C-API documentation / tutorial
won't help me since it is quite difficult to understand because of the
lack of basics.
What do I have to change in order to make the code work?
Thank you very much in advance!
Cheers,
Fabian
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
Georg Brandl wrote: Fabian Steiner wrote: [...] 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);
Why do you use PyInt_AsLong() here? As the documentation says it returns
a long type: long PyInt_AsLong(PyObject *io)
On the other hand I can't find anything like PyInt_AsInt().
if (it == -1 && PyErr_Occurred()) { Py_DECREF(seq);
Why is this Py_DECREF() needed? What does it do exactly? When do I have
to call this function? Obviously, there is also Py_INCREF(). When do you
need this function?
[...] 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 ;)
Now, it compiles fine, without any warnings and using it in Python works
either :-) Now I have to try to understand what the different parts are
doing and why they are necessary.
Thank you very much so far!
Cheers,
Fabian
Fabian Steiner wrote: Georg Brandl wrote: Fabian Steiner wrote: [...] 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);
Why do you use PyInt_AsLong() here? As the documentation says it returns a long type: long PyInt_AsLong(PyObject *io) On the other hand I can't find anything like PyInt_AsInt().
Python's int objects carry a long, so they can return you this long.
On most 32-bit platforms, int == long anyway, but for 64-bit you'd have
to declare list as long too. if (it == -1 && PyErr_Occurred()) { Py_DECREF(seq);
Why is this Py_DECREF() needed? What does it do exactly? When do I have to call this function? Obviously, there is also Py_INCREF(). When do you need this function?
This is for reference counting. Since you created seq with PySequence_Fast
you "own" a reference to it (it has reference count 1). Since nothing else
references that sequence, it has to be deallocated before the function exits.
You use Py_DECREF to decrease the reference count to 0, thus telling Python
that it's safe to free the memory associated with it.
Most API functions that return a PyObject increase its reference count by 1,
leaving you in charge to do something with this ("your") reference.
Other examples of how references can be juggled with:
item = PySequence_Fast_GET_ITEM(seq, i);
PySequence_Fast_GET_ITEM does return a PyObject, but it doesn't increase the
reference count, so you don't have to DECREF item anywhere. However, if you were
to store item in a structure of some sort, you'd have to INCREF it so that
Python doesn't destroy it while it's still referenced by your structure.
PyList_SetItem(newseq, i, PyInt_FromLong(list[i]));
PyInt_FromLong() returns a new PyObject with one reference, but PyList_SetItem
"steals" that reference from you (it stores the PyObject in a structure without
increasing its reference count). Therefore, you don't own a reference to the
integer object anymore and don't have to DECREF it.
newseq = PyList_New(seqlen);
(...)
return newseq;
Here, you own a reference to newseq, but you return the object, so you have to
keep it alive. Thus, no DECREF. [...] 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 ;)
Now, it compiles fine, without any warnings and using it in Python works either :-) Now I have to try to understand what the different parts are doing and why they are necessary.
Cheers,
Georg
Fabian Steiner wrote: What do I have to change in order to make the code work?
I'm afraid to say: your knowledge of C :-)
But don't worry, C is an easy language to learn, and a very valuable
skill to have.
Baalbek This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Rolf Wester |
last post by:
Hi,
I'm just beginning PHP programming. I have installed Apache 2.0.48 and
PHP 4.3.3. The installation went well. Then I was trying a little example.
HTML page:
<html>
<head>...
|
by: Doobai |
last post by:
Hi, hope you can help,
Just starting to learn about objects-relationals and I've come across
what I hope is a little problem, when I try and make the method code,
I get told the type already...
|
by: Fredrik Nelson |
last post by:
Hi,
I have used xsl to transform xml from sqlserver in and it works fine
now i have a webservice that uses a dataset to get the data and return it as
xml
like the code below
<WebMethod()> _...
|
by: trond |
last post by:
Hello all,
I am building a personal web site in VS2005 as a kind of learing
project for myself, so forgive me if this is a novice question.
I am planning to use an XML file called...
|
by: mabond |
last post by:
Hi
Can't get my head round something which I reckon should be simple.
My app has a main form (frmMain). MdiContainer set to true.
A menu item triggers a new form (frmSelect) whose parent is...
|
by: Zahpod |
last post by:
Hi all
The Code:
#include <stdio.h>
#include <sys/ddi.h>
main(int argc, char *argv)
{
int i,dec;
if ( argc < 2 )
|
by: Lars |
last post by:
Hi all
If this is the wrong list for beginners trouble I apologize.
please refer to me the correct list in such case.
I am trying to create a simple linked list but I keep getting segmentation...
|
by: Ivan Reborin |
last post by:
Hello all,
I'm new to python, new as newbies get, so please, don't take wrongly
if this seems like a stupid or overly simple question.
I'm going through examples in a book I have ("Beginning...
|
by: CloudSolutions |
last post by:
Introduction:
For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
| |