Thread View: pl.comp.lang.python
3 messages
3 total messages
Started by kenubi
Wed, 18 Nov 2009 17:13
Python3,c-api,PyUnicode_Decode - niszczy wskaźnik?
Author: kenubi
Date: Wed, 18 Nov 2009 17:13
Date: Wed, 18 Nov 2009 17:13
43 lines
1959 bytes
1959 bytes
Napisałem taką funkcję w swoim module (C) dla testu:
Python 3.1.1
---------------------------------------
wklejam:
static PyObject * py_test1(PyObject *self, PyObject *args)
{
PyObject *SO,*temp;
char *s;
if (!PyArg_ParseTuple(args,"U",&SO)) return NULL;
temp = PyUnicode_AsEncodedString(SO,"iso8859-2","replace");
if ( temp == NULL ) return NULL;
s = PyBytes_AsString(temp);
if ( s == NULL ) return NULL;
Py_DECREF(temp);
printf("<%s>\n",s);
temp = PyUnicode_Decode( s, strlen(s), "iso8859-2","strict");
printf("[%s]\n",s);
return Py_BuildValue("s",s);
}
----------------------------------
jak wołam dla ciągu: "ala,ma,kota " (4 spacje za kota)
to dostaję:
"<ala,ma,kota >"
"[ala,ma,kota ]"
'ala,ma,kota '
a jak dla ciągu: "ala,ma,kota " (5..12 spacji za kota,dla 13 jest O.K.)
to dostaję:
"<ala,ma,kota >"
"[8]"
'8'
?? PyUnicode_(tak, bez jego wywołania nic się nie dzieje) zniszczył
zawartość źródła?
To jest Bug czy ja czegoś nie zrozumiałem?
pozdrawiam
Re: Python3,c-api,PyUnicode_Decode - niszczy wskaźnik?
Author: kenubi
Date: Thu, 19 Nov 2009 10:14
Date: Thu, 19 Nov 2009 10:14
8 lines
1207 bytes
1207 bytes
kenubi wrote: > s = PyBytes_AsString(temp); > Py_DECREF(temp); OK, zapomiałem a dokumentacja przypomniała, że jest zwracany wskaźnik do wewnętrznego bufora (tu obiektu temp) a ja go zaraz potem "niszczę" (DECREF). Także nowy dzień, świeże spojrzenie, rozwiązało problem.
Re: Python3,c-api,PyUnicode_Decode - niszczy wskaźnik?
Author: Rob Wolfe
Date: Thu, 19 Nov 2009 10:53
Date: Thu, 19 Nov 2009 10:53
63 lines
2589 bytes
2589 bytes
kenubi <nono@no.pl> writes:
> Napisałem taką funkcję w swoim module (C) dla testu:
> Python 3.1.1
Błąd tkwi w Twoim kodzie. Patrz niżej.
>
> ---------------------------------------
> wklejam:
>
> static PyObject * py_test1(PyObject *self, PyObject *args)
> {
> PyObject *SO,*temp;
> char *s;
>
> if (!PyArg_ParseTuple(args,"U",&SO)) return NULL;
>
> temp = PyUnicode_AsEncodedString(SO,"iso8859-2","replace");
> if ( temp == NULL ) return NULL;
> s = PyBytes_AsString(temp);
Tu pobierasz wskaźnik do wewnętrznego bufora obiektu `temp`
a nie jego kopię [1]_.
> if ( s == NULL ) return NULL;
> Py_DECREF(temp);
A tu zwalniasz pamięć obiektu `temp` wraz z jego wewnętrznym buforem.
Wszystko co się dalej dzieje leży w rękach GC i przypadkowej
zawartości bufora, na który wskazuje `s`.
>
> printf("<%s>\n",s);
> temp = PyUnicode_Decode( s, strlen(s), "iso8859-2","strict");
> printf("[%s]\n",s);
>
> return Py_BuildValue("s",s);
> }
>
> ----------------------------------
> jak wołam dla ciągu: "ala,ma,kota " (4 spacje za kota)
> to dostaję:
> "<ala,ma,kota >"
> "[ala,ma,kota ]"
> 'ala,ma,kota '
>
> a jak dla ciągu: "ala,ma,kota " (5..12 spacji za kota,dla 13 jest O.K.)
> to dostaję:
> "<ala,ma,kota >"
> "[8]"
> '8'
> ?? PyUnicode_(tak, bez jego wywołania nic się nie dzieje) zniszczył
> zawartość źródła?
> To jest Bug czy ja czegoś nie zrozumiałem?
Dlatego tak kocham ręczne zarządzanie pamięcią.
Błąd popełniony w jednym miejscu może doprowadzić do wysnuwania
szalonych teorii w innym. ;)
.. [1] http://docs.python.org/3.1/c-api/bytes.html?highlight=pybytes_asstring#PyBytes_AsString
RW
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads