Nick Craig-Wood skrev: > Sheldon <[EMAIL PROTECTED]> wrote: > > Man. You are good. This is most insight I have had from anyone. > > :-) > > > I did initialize the arrays with PyObjects and today, after hours of > > debugging and now with your insight, I think the problem lies here: > > Good! > > You need to release some python references otherwise you'll have a > memory leak and copy some strings you don't own > > It is worth reading the definitions for those functions in the Python > API docs > > http://docs.python.org/api/api.html > > In particular read about reference counts. > > With the Python C API you have to know at all time (by reading the > doc) whether you own the reference or not, and whether you own the > memory or not. > > > /* here a python list of strings is read into a C string array */ > > 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[i] = PyString_AsString(msgop); > > work.msg_scenes[i] = strdup(PyString_AsString(msgop)); > Py_DECREF(msgop); > > > ppsop = PyList_GetItem(work.ppsobj, i); > > work.pps_scenes[i] = PyString_AsString(ppsop); > > work.pps_scenes[i] = strdup(PyString_AsString(ppsop)); > Py_DECREF(ppsop); > > > } > > for (i = 0; i < NumberOfTiles; i++) { > > tileop = PyList_GetItem(work.tileobj, i); > > work.tiles[i] = PyString_AsString(tileop); > > work.tiles[i] = strdup(PyString_AsString(tileop)); > Py_DECREF(tileop); > > > sceneop = PyList_GetItem(work.nscenesobj, i); > > work.nscenes[i] = PyInt_AsLong(sceneop); > > Py_DECREF(sceneop); > > > } > > return 1; > > } /*end readPythonObject*/ > > You free() the strings later which is fine. > > The above ignores errors which PyList_GetItem may return and strdup() > returning 0, but it should get you out of trouble hopefully. > > ... > > I've written lots of quite similar code, here is a snippet. Note the > comments about who owns the reference, and the error checking. Also > note xstrdup() which is a strdup() which blows up if no memory is > available. > > [snip] > PyObject *item = PySequence_GetItem(value, i); /* real ref */ > if (item == 0) > { > fprintf(stderr, "Failed to read '%s[%d]' attribute\n", name, i); > goto err; > } > item_cstr = PyString_AsString(item); /* borrowed */ > if (item_cstr == 0) > { > fprintf(stderr, "Failed to read '%s[%d]' as string\n", name, i); > goto err; > } > label[i] = xstrdup(item_cstr); > Py_DECREF(item); > item = 0; > [snip] > err:; > PyErr_Print(); > out:; > if (value) > Py_DECREF(value); > if (item) > Py_DECREF(item); > return rc; > > > -- > Nick Craig-Wood <[EMAIL PROTECTED]> -- http://www.craig-wood.com/nick
Thanks Nick! Man, I really appreciate this. I did dereference before but the program crashed and I did understand why so I kept on learning. Now I have your snip. Much obliged. I will be adding Numpy to my new PC in Jan and there I can pass arrays instead of list. Still, I would like to save your email address i case I have some mre questions later - if that ok with you? I will make the changes and try to run the code. /S -- http://mail.python.org/mailman/listinfo/python-list