NullReferenceException
-
Hallo zusammen,
habe ein "sprachliches" Problem mit .net:
Um bei einer verketteten Liste zu überprüfen, ob schon ein Objekt vorhanden ist in C++:
First* Item;
Item = NULL;
...
if (First == NULL)
{Erstes Element erstellen}aber jetzt als managed Code habe ich folgendes Problem:
...
Item = nullptr;
...
if (First == nullptr) <= an dieser Stell stürzt das Programm ab mit der Fehlermeldung:
Unbehandelte System.NullReferenceException usw.Wie kann ich überprüfen, ob schon ein Objekt existiert?
Vielen Dank im voraus.
-
Vielleicht hilft das:
http://msdn2.microsoft.com/en-us/library/4ex65770.aspxAnsonsten poste doch ein wenig mehr Code.
-
Also der Code:
struct Item{
double Value[7];
Item* next;
};...
In Speicher.h sind First und Last als Pointer des Typs Item deklariert.
...Speicher::Speicher(void)
{
First = nullptr;
Last = nullptr;
}Speicher::NeuerWert(double Wert1, double Wert2, double Wert3, double Wert4, double Wert5, double Wert6, double Zeit)
{
Item* Park;
if (First == nullptr) <--- An dieser Stelle stürzt das Programm ab.
{
First = new Item;
Park = First;
}
...
}Ich muss also irgentwie überprüfen, ob der Pointer First schon auf ein gültiges Objekt zeigt, oder noch nicht gesetzt ist.
-
Irgendwie sieht es für mich so aus, dass das einzige was hier aus der managed Welt kommt der nullptr ist. Warum nimmst Du nicht einfach 0??
-
genau, du kannst keine managed pointer mit == nullptr vergleichen
unmanagedPointer == NULL und managedPointer == nullptr
und ZOMGF bitte nenn die variablen gescheit
klassen, strukturen usw werden groß geschrieben und instanzen werden klein geschrieben, so wie du es hast ist das mehr als unleserlich
außerdem ist es irreführend ein "First" und "Last" zu typedeffen mit Item *
wenn schon mach ein typedef auf ItemPtr zu Item * und dann
ItemPtr first = NULL;
ItemPtr last = NULL;außerdem, was soll dann das hier
First* Item;
Item = NULL;
...
if (First == NULL)
{Erstes Element erstellen}First ist ja wie du geschrieben hast ein Item *, dann ist First * ein Item **
hast du ein array aus Item * auf first gespeichert?! ich denke nicht, das sollte wohl heißen
First Item; anstatt von First *Item;
abgesehen davon wenn First definiert ist als Item * dann ist Item selbst ein typ und du darfst die variable dort garnicht "Item" nennen weil das schon der name von einem typ ist (wo wir wieder bei groß/klein schreibung sind, nenn es "item" mit nem lowercase i)
und das if(First == NULL) war wohl auch gemeint als if(Item == NULL).... -.-
-
genau, du kannst keine managed pointer mit == nullptr vergleichen
Ehm.. genau verkehrt oder?
unmanagedPointer == NULL und managedPointer == nullptr
Interessanterweise sollte, laut dem oben geposteten MSDN Link, beides gehen.
@Matze:
Hast Du mit /clr kompiliert?
-
simon.gysi schrieb:
genau, du kannst keine managed pointer mit == nullptr vergleichen
Ehm.. genau verkehrt oder?
ja -.-
ok ich habs mal schnell getestet
float *x = NULL; if(x == nullptr) void;
funktioniert ganz normal, also scheinbar ist es doch ein ersatz für NULL
bzw hab ich erst jetzt verstanden wie er das meint mit First und Last sind pointer von item... also Item *First, *Last; -.-
ich dachte er meint typedef lolwenn der compiler bei First == NULL abstürzt, dann nehme ich an ist "Speicher" eine ref class, und der member "First" selbst hat wenn du im debugger schaust den wert "undefined value" (er zeigt also nicht auf null sondern ist selbst null)
das ist mir auch schon mal passiert (aber auch nur mit c++/cli -.-), normalerweise würde ja der fehler schon kommen wenn du die methode NeuerWert aufrufst über einen null pointer
ich hab allerdings ka mehr was damals nicht gepasst hat, müsstest mehr code posten anstatt diese komischen codeschnipsel, und fang an deinen code besser zu formatieren
-
Danke für die bisherigen Antworten, formatierung ist in arbeit
So sieht ITEM aus
struct ITEM { double value[7]; Item* next; //Zeigt auf's nächste Element };
ref class SPEICHER { public: SPEICHER(void); bool NeuerWert(System::Double wert1, noch weitere doubles); bool NächsterWert(ITEM* park); protected: ITEM* first; //Zeigt auf's erste Element ITEM* last; //Zeigt auf's letzte Element };
Das ganze soll ein FIFO-Speicher werden, also bei last kommt was neues dran, und bei first wird ausgelesen und dann gelöscht.
bool SPEICHER::NeuerWert(double Wert1, double Wert2, double Wert3, double Wert4, double Wert5, double Wert6, double Zeit) { ITEM* park; if (first == nullptr) { first = new Item; park = First; } else { last->next = new Item; park = last; last = last->next; } // Jetzt werden nur noch die Werte übergeben return true; }
Und vor dem Absturz ist's wie Vevusio geschrieben hat => "undefined value".
-
Benutze mal new Item(); anstelle von new Item;
-
Für mich ist immer noch schleierhaft was das ganze mit C++/CLI zu tun hat.
Das ref class und der nullptr sind ja bei deinen Impl. nicht nötig.
Fall Du nämlich eine verkettete Liste suchst.. die gibts schon unter System::Collections::Generic::LinkedList (managed) und unter std::list in der STL.Bitte um Erklärung.
-
Der Rest des Projektes ist in C++/CLI, also Oberfläche usw.
Ich probier das mit simon.gysi's vorschlag der (managed) LinkedList
Wusste nicht, dass es das schon fertig gibt.
Danke für die hilfe.
-
du solltest keine liste verwenden anstelle einer queue (fifo) oder eines stacks (lifo)
wenn du das .NET framework dafür verwenden willst dann nimm die generische queue klasse aus dem 3.5 .NET framework
http://msdn2.microsoft.com/en-us/library/7977ey2c.aspx
oder die nicht generische version aus einem älteren, bzw könntest du auch die funktionalität einer queue um eine generische liste herum kapseln in einer eigenen klasse, allerdings nicht direkt eine liste verwenden
und dein absturz liegt nicht an dem code in der klasse SPEICHER selbst sondern daran wie du sie benutzt, also das äußere nicht innere der klasse (zumindest ist an der klassen, methoden und struktur definition nichts falsch soweit ich das sehe)