Hi BlackJack!
Das ist mir schon klar gewesen. Musste nur, wie geschrieben, an den Zeigefinger des Profs denken.
Das mit dem strukturierten Programmcode kommt so langsam glaube ich auch.
Python/C - [[],[],[],...] an Python übergeben
Hallo Heiko!
Bin jetzt dazu gekommen, deinen Vorschlag mal zu Bearbeiten.
Also Problem Nr. 1 ist, dass ich eine Liste als inneres Array brauche und kein Tuple. - Das liesse sich aber wohl noch lösen.
Das Andere Problem liegt jetzt in meinem Verständnis und zwar:
Warum ist bei nem Tuple das Setzen eines items nicht so fehlerkritisch, als bei einer Liste? Das Stehlen der Referenz habe ich doch analog auch bei der Liste.
Desweiteren habe ich jetzt mal mit dem Workaround
#ifdef _DEBUG
#undef _DEBUG
#include "python.h"
#define _DEBUG
#else
#include "python.h"
#endif
das Debuggen mit MsVC ans Laufen bekommen. Hier zeigt sich, das der Referenzzähler des PyData vor dem XDECREF auf 1 steht und danach 14731456 aufweist. Wodurch ist das zu erklären?
Bin jetzt dazu gekommen, deinen Vorschlag mal zu Bearbeiten.
Also Problem Nr. 1 ist, dass ich eine Liste als inneres Array brauche und kein Tuple. - Das liesse sich aber wohl noch lösen.
Das Andere Problem liegt jetzt in meinem Verständnis und zwar:
Warum ist bei nem Tuple das Setzen eines items nicht so fehlerkritisch, als bei einer Liste? Das Stehlen der Referenz habe ich doch analog auch bei der Liste.
Desweiteren habe ich jetzt mal mit dem Workaround
#ifdef _DEBUG
#undef _DEBUG
#include "python.h"
#define _DEBUG
#else
#include "python.h"
#endif
das Debuggen mit MsVC ans Laufen bekommen. Hier zeigt sich, das der Referenzzähler des PyData vor dem XDECREF auf 1 steht und danach 14731456 aufweist. Wodurch ist das zu erklären?
-
- User
- Beiträge: 670
- Registriert: Sonntag 15. Januar 2006, 18:42
- Wohnort: Celle
- Kontaktdaten:
Eben nicht. Wenn Du PyList_Append() machst wird von der Liste eine neue Referenz auf das Objekt gespeichert, bei PyTuple_SET_ITEM() wird eine Referenz gestohlen. Ersteres kann also aus welchem Grund auch immer fehlschlagen (zum Beispiel weil die Liste nicht verlängert werden kann), zweiteres kann nie fehlschlagen, weil der Platz schon vorallokiert ist, deswegen ist es auch ein Makro, während ersteres eine Funktion ist.Warum ist bei nem Tuple das Setzen eines items nicht so fehlerkritisch, als bei einer Liste? Das Stehlen der Referenz habe ich doch analog auch bei der Liste.
Wenn Du umbedingt Listen brauchst kann ich auch Code dafür machen, der sieht aber dann nicht mehr ganz so schön kompakt aus.
Wenn der Referenzzähler vorher auf 1 war ist das Objekt nach dem Py_XDECREF unbrauchbar (also freigegeben). Deswegen ist auch der Referenzzähler nicht mehr zu gebrauchen (bzw. der Inhalt unsinnig, und nicht notwendigerweise 0).Hier zeigt sich, das der Referenzzähler des PyData vor dem XDECREF auf 1 steht und danach 14731456 aufweist. Wodurch ist das zu erklären?
--- Heiko.
Dass das bei PyList_Append() auftaucht ist mir vollkommen einleutend gewesen.
Mein Prob liegt darin, das du nen neuen Tuple erzeugen kannst
und dass dieses(?) Tuple dann allokierten Speicher besitzt.
PyList_New(0) aber ja anscheinend nicht...
Das mit dem Referenzzähler leuchtet ein.
Mein Prob liegt darin, das du nen neuen Tuple erzeugen kannst
Code: Alles auswählen
if( !( PyARB_Point = PyTuple_New(0) ) ) goto end_error;
PyList_New(0) aber ja anscheinend nicht...
Untersteh dich! Ich wills selber verstehen. Copy-Paste bringt mir da nicht so wirklich viel. - Aber Danke!Wenn Du umbedingt Listen brauchst kann ich auch Code dafür machen, der sieht aber dann nicht mehr ganz so schön kompakt aus. Wink
Das mit dem Referenzzähler leuchtet ein.
-
- User
- Beiträge: 670
- Registriert: Sonntag 15. Januar 2006, 18:42
- Wohnort: Celle
- Kontaktdaten:
Das war nicht ganz richtig was ich da geschrieben hab, das ist mir aber erst jetzt aufgefallen, und es ist erstaunlich dass es anscheinend trotzdem lief, oder?Mein Prob liegt darin, das du nen neuen Tuple erzeugen kannst
Auf jeden Fall sollte das sein:
Code: Alles auswählen
if( !( PyARB_Point = PyTuple_New(3) ) ) goto end_error;
Bei Listen stellt man mit dem entsprechenden Parameter ein vieviele Elemente vorallokiert sind (also wie groß das Array am Anfang _mindestens_ sein soll, meißtens ist es größer, weil Python bestimmte Schritte verwendet). Wenn Du dann einen PyList_Append machst und vorher schon mit Größe drei vorallokiert hast wird PyList_Append eigentlich nie fehlschlagen können, weil die Liste ja schon besteht. Dafür müßtest Du Dir aber den Quellcode noch mal genauer angucken. Zumindest würde mir da auch nix einfallen was fehlschlagen könnte.
Auf jeden Fall stiehlt PyList_Append die Referenz eben nicht (soweit ich weiß, wohlgemerkt, aber ich hab gerade im Handbuch nachgeguckt und da steht nix gegenteiliges), während PyTuple_SET_ITEM das sehr wohl macht. Dementsprechend mußt Du wenn Du ersteres benutzt das Element was Du in die Liste einträgst Py_DECREF()-fen, damit nur noch die Referenz aus der Liste draufzeigt, und keine "dangling reference" besteht die vergessen wird wenn Deine Methode sich beendet.
--- Heiko.
Pui, die 3 beruhigt mich jetzt aber extrem!
Hab echt schon vollkommen an mir selbst gezweifelt.
Das ganze Prob ist doch dann ebenso nicht vorhanden, wenn ich PyList_NewList(3) verwende, um eine Liste statt eines Tuples zu erstellen.
Bei PyList_SET_ITEM(x, y, z) verhält es sich ja analog zum Tuple, denn hier wird ja auch die Referenz gestohlen.
Sprich(Schreib): Der Knackpunkt wäre dann das PyList_NewList(3), denn dort wird der Speicher allokiert. Wenn ich dann in der For-Schleife weiter mit PyList_SET_ITEM(x,y,z) arbeite, allokiere ich ja keinen Speicher neu. Ich spiele lediglich Räuber Hotzenplotz mit den Referenzen der item.
Beim PyList_Append der 2-dimensionalen Liste am Ende der FOR-Schleife muss ich dann selbstverständlich wieder Py_DECREF()-fen.
Hab echt schon vollkommen an mir selbst gezweifelt.
Das ganze Prob ist doch dann ebenso nicht vorhanden, wenn ich PyList_NewList(3) verwende, um eine Liste statt eines Tuples zu erstellen.
Bei PyList_SET_ITEM(x, y, z) verhält es sich ja analog zum Tuple, denn hier wird ja auch die Referenz gestohlen.
Sprich(Schreib): Der Knackpunkt wäre dann das PyList_NewList(3), denn dort wird der Speicher allokiert. Wenn ich dann in der For-Schleife weiter mit PyList_SET_ITEM(x,y,z) arbeite, allokiere ich ja keinen Speicher neu. Ich spiele lediglich Räuber Hotzenplotz mit den Referenzen der item.
Beim PyList_Append der 2-dimensionalen Liste am Ende der FOR-Schleife muss ich dann selbstverständlich wieder Py_DECREF()-fen.