Cpoying a PyList to a C string array

S

Sheldon

Hi,

The code below is a rookie attempt to copy a python list of strings to
a string array in C. It works to some extent but results in memory
problems when trying to free the C string array. Does anyone know how
to do this properly?

***********************************************************
/*Read an list of strings from a python object*/
static int readPythonObject(void) {

int i;
PyObject *msgop;
PyObject *ppsop;
PyObject *tileop;
PyObject *sceneop;

for (i = 0; i < work.sumscenes; i++) {
msgop = PyList_GetItem(work.msgobj, i);
work.msg_scenes = PyString_AsString(msgop);
ppsop = PyList_GetItem(work.ppsobj, i);
work.pps_scenes = PyString_AsString(ppsop);
}
for (i = 0; i < NumberOfTiles; i++) {
tileop = PyList_GetItem(work.tileobj, i);
work.tiles = PyString_AsString(tileop);
sceneop = PyList_GetItem(work.nscenesobj, i);
work.nscenes = PyInt_AsLong(sceneop);
}
return 1;
} /*end readPythonObject*/

*******************************************

/S
 
K

Klaas

Sheldon said:
The code below is a rookie attempt to copy a python list of strings to
a string array in C. It works to some extent but results in memory
problems when trying to free the C string array. Does anyone know how
to do this properly?

You have numerous problems in this code. The most important problem is
that you are referring to global variables which appear to be c structs
but you don't provide the definition (e.g., "work"). However, I can
guess some of the issues:
for (i = 0; i < work.sumscenes; i++) {
msgop = PyList_GetItem(work.msgobj, i);
work.msg_scenes = PyString_AsString(msgop);
ppsop = PyList_GetItem(work.ppsobj, i);
work.pps_scenes = PyString_AsString(ppsop);
}


PyString_AsString returns a pointer to the internal buffer of the
python string. If you want to be able to free() it (or indeed have it
exist for beyond the lifetime of the associated python string), you
need to malloc() memory and strcpy() the data. If the strings contain
binary data, you should be using PyString_AsStringAndSize. see
http://docs.python.org/api/stringObjects.html.

I notice that you are doing no error checking or ref counting, but my
(inexperienced python c programming) opinion is that it should work
(neither api could potentially call python code, so I don't think
threading is an issue).
for (i = 0; i < NumberOfTiles; i++) {
tileop = PyList_GetItem(work.tileobj, i);
work.tiles = PyString_AsString(tileop);
sceneop = PyList_GetItem(work.nscenesobj, i);
work.nscenes = PyInt_AsLong(sceneop);
}
return 1;


Similarly.

-Mike
 
S

Sheldon

Klaas skrev:
Sheldon said:
The code below is a rookie attempt to copy a python list of strings to
a string array in C. It works to some extent but results in memory
problems when trying to free the C string array. Does anyone know how
to do this properly?

You have numerous problems in this code. The most important problem is
that you are referring to global variables which appear to be c structs
but you don't provide the definition (e.g., "work"). However, I can
guess some of the issues:
for (i = 0; i < work.sumscenes; i++) {
msgop = PyList_GetItem(work.msgobj, i);
work.msg_scenes = PyString_AsString(msgop);
ppsop = PyList_GetItem(work.ppsobj, i);
work.pps_scenes = PyString_AsString(ppsop);
}


PyString_AsString returns a pointer to the internal buffer of the
python string. If you want to be able to free() it (or indeed have it
exist for beyond the lifetime of the associated python string), you
need to malloc() memory and strcpy() the data. If the strings contain
binary data, you should be using PyString_AsStringAndSize. see
http://docs.python.org/api/stringObjects.html.

I notice that you are doing no error checking or ref counting, but my
(inexperienced python c programming) opinion is that it should work
(neither api could potentially call python code, so I don't think
threading is an issue).
for (i = 0; i < NumberOfTiles; i++) {
tileop = PyList_GetItem(work.tileobj, i);
work.tiles = PyString_AsString(tileop);
sceneop = PyList_GetItem(work.nscenesobj, i);
work.nscenes = PyInt_AsLong(sceneop);
}
return 1;


Similarly.

-Mike


Thanks Mike,

I am rewriting the code but I don't understand the part about the c
struct variable called work. The function I posted is a part of a
larger script and I just posted that part that was problamatic. I was
under the impression that if I declared the structure as global with
the variable in tow:

struct my_struct {
int var;
} work;

then this is visible everywhere in the function as long as everything
is in one file. Did I miss something?

/S
 
K

Klaas

Sheldon said:
Thanks Mike,

I am rewriting the code but I don't understand the part about the c
struct variable called work. The function I posted is a part of a
larger script and I just posted that part that was problamatic. I was
under the impression that if I declared the structure as global with
the variable in tow:

struct my_struct {
int var;
} work;

then this is visible everywhere in the function as long as everything
is in one file. Did I miss something?

It's not important how you declare the struct. It matters what is in
the struct (in particular, the data types of the members, and what
initialization you've done to them).

The important part was the rest of my message.

-Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top