Py_INCREF() incomprehension
Hegedüs Ervin
airween at gmail.com
Tue Apr 26 07:01:13 EDT 2011
Hello,
thanks for the reply,
> >static PyObject*
> >mycrypt_encrypt(PyObject *self, PyObject *args)
> >{
> > int cRes = 0;
> > int OutLen = 0;
> >
> > char * url;
> > char * path;
> >
> > if (!PyArg_ParseTuple(args, "ss",&url,&path)) {
>
> Use the "s#" format instead to get the length as well.
oh, thanks, I'll check it out,
> > return NULL;
> > }
> >
> > OutLen = strlen(url)*4;
> > outdata=calloc(OutLen, sizeof(char));
> >
> > if (!outdata) {
> > handle_err(UER_NOMEM);
>
> I assume this raises MemoryError?
yes,
another question should be: do I need to use
Py_INCREF()/Py_DECREF() at exception objects?
There are several error types, which has defined in 3rd-party
header file, based on these I've created my exceptions:
...
static PyObject *cibcrypt_error_badparm;
static PyObject *cibcrypt_error_nomem;
static PyObject *cibcrypt_error_badsize;
...
void handle_err(int errcode) {
switch(errcode) {
...
case -4: PyErr_SetString(cibcrypt_error_badparm, "Bad parameter");
break;
case -5: PyErr_SetString(cibcrypt_error_nomem, "Not enough memory");
break;
case -6: PyErr_SetString(cibcrypt_error_badsize, "Invalid buffer size");
break;
...
}
PyMODINIT_FUNC
initcibcrypt(void)
{
PyObject *o;
o = Py_InitModule3("mycrypt", mycrypt_methods, mycrypt_doc);
...
cibcrypt_error_badparm = PyErr_NewException("cibcrypt.error_badparm", NULL, NULL);
cibcrypt_error_nomem = PyErr_NewException("cibcrypt.error_nomem", NULL, NULL);
cibcrypt_error_badsize = PyErr_NewException("cibcrypt.error_badsize", NULL, NULL);
...
PyModule_AddObject(o, "error", cibcrypt_error_badparm);
PyModule_AddObject(o, "error", cibcrypt_error_nomem);
PyModule_AddObject(o, "error", cibcrypt_error_badsize);
...
}
is that correct?
> > return NULL;
> > }
> > cRes = ekiEncodeUrl (url, strlen(url)+1, outdata,&OutLen, 1, path);
> >
> > if (cRes == 0) {
> > return Py_BuildValue("s", outdata);
>
> You are leaking the memory allocated for outdata here.
ok, and how can I handle that leak? When should I use the
Py_DECREF, or any other function (eg: free()?))?
> And, again, use the "s#" format.
>
>
> > } else {
> > handle_err(cRes);
> > return NULL;
> > }
>
> I assume this raises an appropriate exception?
yes, see the handle_error() function.
>
> > return Py_None;
>
> This is unreachable code.
yes, that's just an old typo, I think I purged these... thanks.
> >where ekiEncodeUrl is in a 3rd-party library.
> >I should call this function from Python like this:
> >
> >import mycrypt
> >
> >message = "PID=IEB0001&MSGT=10&TRID=000000012345678"
> >crypted = mycrypt(mymessage, "/path/to/key");
> >
> >Everything works fine, but sorry for the recurrent question: where
> >should I use the Py_INCREF()/Py_DECREF() in code above?
>
> These two functions are not your problem here.
which two functions did you mean?
If you mean encrypt/decrypt (above), why did you wrote there is a
memleak?
> In any case, I recommend using Cython instead of plain C. It keeps
> you from getting distracted too much by reference counting and other
> CPython C-API details, so that you can think more about the
> functionality you want to implement.
ok, I'll try to see CPython, but - just for my passion :) - what
is the solution to handle the leak above?
Thanks again:
a.
More information about the Python-list
mailing list