[Tutor] python lists to C arrays and vice versa

Viktor Hornak hornak at csb.sunysb.edu
Mon Feb 7 15:27:56 CET 2005


Hello All,

I've been trying to find more resources/documentation about how to 
convert python lists to C arrays (and vice versa) when writing a python 
extension. Surprisingly, there's very little one can find about this 
even though it must be a fairly common procedure. I looked through 
official python guide on "Extending and Embedding the Python 
Interpreter" but it's very terse on examples and the important topic on 
reference counting is still not very clear. I also found one or two 
examples of similar operations on this list postings (from 6 years ago!) 
but they didn't quite explain all I need to know.
Here is the code I was trying to use to convert two lists (one is a list 
of strings with the same length and the other is a list of doubles) to C 
arrays in a C extension:


typedef char Name[5];
extern void parseMask(int, char*, Name *, double *);  /* this is the 
function I am
                                                         trying to wrap */

static PyObject *print_sel(PyObject *self, PyObject *args)
{
   PyObject *anamestr, *xdbl;
   PyObject *pylist;  /* return list of 0/1 */
   PyObject *item;
   int nat;
   int i, k;
   Name *aname;
   double *x;

   PyArg_ParseTuple(args,"iOO", &nat, &anamestr, &xdbl);
   if (!PySequence_Check(anamestr) || !PySequence_Check(xdbl)) {
      PyErr_SetString(PyExc_TypeError, "expected sequence");
      return NULL;
   }
   /* create dynamic C arrays */
   aname = (Name *) malloc(sizeof(Name)*nat);
   x = (double *) malloc(sizeof(double)*nat);

   for (i = 0; i < nat; i++) {
      /* get the element from the list*/
      item = PySequence_GetItem(anamestr,i);
      /* check that item != NULL, i.e. make sure it is Python string */
      if (!PyString_Check(item)) {
         free(aname);  /* free up the memory before leaving */
         free(x);
         PyErr_SetString(PyExc_TypeError, "expected sequence of strings");
         return NULL;
      }
      /* assign to the C array */
      strcpy(aname[i], PyString_AsString(item));
      Py_DECREF(item);

      item = PySequence_GetItem(xdbl,i);
      if (!PyFloat_Check(item)) {
         free(aname);
         free(x);
         PyErr_SetString(PyExc_TypeError, "expected sequence of integers");
         return NULL;
      }
      x[i] = PyFloat_AsDouble(item);
      Py_DECREF(item);
   }

Then I call the function "parseMask" (which I am trying to wrap in this 
extension) which returns a C array (integer array, elements are either 0 
or 1). Now I need to convert this integer array to python list and 
return it back to python. Here is the code for that:

   result = (int *) malloc(sizeof(int) * nat);
   parseMask(...) -> returns int array result

   pylist = PyTuple_New(nat);
   for (i = 0; i < nat; i++) {
      /* convert resulting array [0/1] to PyObject */
      if (result[i] == 0)
         item = PyInt_FromLong(0);
      else
         item = PyInt_FromLong(1);

      PyTuple_SetItem(pylist, i, item);
      Py_DECREF(item);
   }

   /* free up all arrays before leaving */
   free((void *) aname);
   free((void *) x);
   free((void *) result);

   return pylist;


I was wondering if some 'extension guru' (or whoever has experience with 
writing extensions :-)) could see if the above code is correct, 
especially with respect to reference counting. When I use this extension 
from Python (on Fedora Core 3, Python2.3) I get the following error:

*** glibc detected *** double free or corruption (out): 0x09f724e8 ***
Aborted

This is supposed to mean some deeper memory allocation/deallocation 
error. I suspect I am not creating or releasing python objects in my C 
extension above correctly. Of course, it is also possible that the C 
function I am wrapping (parseMask()) is not allocating memory properly, 
but it works without problem when I call it from a C program.
I am sorry for this looong post, but I didn't see a way to make it 
shorter and still be very specific about what I am trying to do...

Many thanks for any help,
-Viktor Hornak



More information about the Tutor mailing list