NULL pointer

Status
Niet open voor verdere reacties.

Westerland

Gebruiker
Lid geworden
27 jun 2011
Berichten
286
Goedemiddag,

Ik zat met het volgende probleem.

Bij het entrypoint van een deel van de code maak ik een pointer aan van het type SquareObject (wordt geinit als NULL).


[cpp]
//maya command entrypoint. nee heb de naam doIt niet verzonnen xD
MStatus RoomCommand::doIt(const MArgList& args)
{
MStatus status;

SquareObject *objectInstance = NULL;

status = argParser(args,&createValue,objectInstance);
}
[/cpp]

Vervolgens verstuur ik deze pointer naar een methode waar die gezet wordt op basis van argumenten.
FieldOfInterest en RoomObject erven over van SqaureObject.


[cpp]

MStatus RoomCommand::argParser(const MArgList& args, int *objectCreation, SquareObject *objectInstance){

bool createCommandFound = false;

flagIndex = args.flagIndex(fieldFlag,fieldLongFlag);

//if fieldFlag has been found
if (MArgList::kInvalidArgIndex != flagIndex)
{
createCommandFound = true;
objectInstance = dynamic_cast<SquareObject*>(FieldOfInterest::getInstance());
*objectCreation = 1;
}

flagIndex = args.flagIndex(roomFlag,roomLongFlag);

//if roomFlag has been found
if (MArgList::kInvalidArgIndex != flagIndex)
{
createCommandFound = true;
objectInstance = dynamic_cast<SquareObject*>(RoomObject::getInstance());
*objectCreation = 2;
}


//check for null pointer
if (objectInstance == NULL)
{
MGlobal::displayError("Nullpointer found at -> RoomCommand::ArgParser at objectInstance");
return MS::kFailure;
}

//overige dingen die niet relevant zijn ??

//einde overige dingen

DEBUG(MString() + (int)objectInstance);

DEBUG("RoomCommand::argParser -> completed");

return status;


}

[/cpp]

de laatste regel van de methode argParser print voordat die returned nog even de pointer af van objectInstance. dit doet die netjes.

maar wanneer ik objectInstance wil gebruiken in de hierboven genoemde methode is die null:


[cpp]
MStatus RoomCommand::doIt(const MArgList& args)
{
MStatus status;

SquareObject *objectInstance = NULL;

status = argParser(args,&createValue,objectInstance);

//dit print 0 uit.
DEBUG(MString() + (int)objectInstance);
}
[/cpp]


Iemand een idee ??
 
Laatst bewerkt:
Ik weet niet hoe de pointers verder gebruikt worden, maar ik neem aan dat je de pointer objextinstance wil vullen met een pointer naar een squareobject?

De 'createvalue int' dereference je wel (*objectcreation) je objectinstance niet. Je stuurt twee pointer mee met de functie, de int vul je met een waarde, het squareobject verander je van pointer (en de waarde van deze pointer kan 0 zijn)
 
Dat klopt ja, objectInstance moet een pointer worden naar Room of FieldOfInterest. de int waarde heb ik er niet ingezet (deze gaat goed).

ik dereference de objectCreation omdat ik er een waarde in wil stoppen. maar de objectInstance hoef je toch niet de dereference als je de pointer van de singleton wil hebben ?
 
[CPP]int test (int *a, int *b)
{
a = b;
return *a+*b;
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 6;
cout << test (&a,&b);
cout << "\n";
cout << a;
cout << "\n";
cout << b;
cout << "\n";
system("PAUSE");
return EXIT_SUCCESS;
}[/CPP]

in de subroutine maak ik a=b. De uitkomst daarvan 12. Echter, omdat ik niet dereference maak ik nu een nieuwe lokale "a" aan. Bij de output van a en b zie je dat a niet 6 is, maar nog steeds 5. De originele pointer is dus niet veranderd.
 
Aha, nu zie ik wat ik fout gedaan heb :-) ik zal even kijken of ik dit kan toepassen. Wederom bedankt voor de hulp ! denk dat ik er zo wel uit moet komen.
 
Dit is een van de redenen dat ik voor hobby gebruik tegenwoordig in C# werk. Pointers en references zijn extreem krachtige dingen, maar samen met scoping is het soms teveel werk om het goed te doen (en vooral om te begrijpen als het fout gaat) :)
 
Ja c# en java beheers ik al en als daar wat fout gaat is dat in de regel een stuk makkelijker te debuggen alleen voor het project (afstudeer project) moet er een maya plugin gemaakt worden en om een zware berekening uit te voeren zal je dan toch echt c++ moeten gebruiken (verder is het ook een + als je c++ beheerst). Een andere optie was om python te gebruiken maar dat vind ik niet echt lekker programmeren :P
 
Ik kom van de andere kant ( C > C++ > C# > python) en ik vind python zeer aardig. Het is ook onverwacht krachtig voor veel taken. Natuurlijk blijft C++ ook gewoon een extreem leuke en krachtige taal, maar je bent echt bezig data te manipuleren op een extreem laag niveau. Soms mis ik dat in C# als ik een hoop data wil manipuleren, maar te vaak wil ik thuis gewoon wat werkend hebben en niet lopen emmeren met eindeloze definities en datatypes om .5 seconde winst te halen.
 
Dat zeker ja, alleen moet ik zeggen nu ik met c++ bezig ben er toch wel een wereld voor me open gaat. Erg leuke uitdaging om het te programmeren :)

Verder is het probleem nu wel enigsinds opgelost alleen gaan er nog wat dingen fout.

wat ik denk dat die doet bij de volgende regel: een copy van de SquareObject maken
[cpp]
*objectInstance = *(dynamic_cast<FieldOfInterest*>(FieldOfInterest::getInstance()));
[/cpp]

wat ik wil dat die doet:
FieldOfInterest singleton instance casten naar een SquareObject zodat ik de methodes van SquareObject kan gebruiken (die dus ook in de singleton FieldOfInterest zijn).

het probleem is namelijk dat als ik later de singelton van FieldOfInterest aanroep, de waardes niet geset zijn.

Weet je misschien een betere manier om dit aan te pakken aangezien ik het idee heb dat ik op het verkeerde spoor ben.

heb even snel een testproject in elkaar gezet om te demonstreren wat ik wil wil dat die doet
http://dl.dropbox.com/u/3380837/Test.7z
 
hmm Ik zie het al, totaal op het verkeerde spoor :D ik zal de constructie anders moeten maken
 
Dat kan, je kunt natuurlijk ook een pointer naar pointer meesturen en die pointer in je hoofdfunctie casten naar square.

Dat is de oplossing die microsoft in principe ook toepast in veel van zijn producten. Alles is "object" en objects mag je vrijelijk doorsturen, totdat je ze cast naar een specifiek type.
 
Hmm dan zal ik dat straks even proberen. Dan moet gewoon als parameter **objectInstance meesturen? Ik heb het nog even in c# geprobeerd maar daar lukte die constructie niet. E enige manier om het in c# voor elkaar te krijgen was om square lokaal in de methode te declaren
 
Heb je de eigenschap in de functie wel als ByRef meegestuurd? Maar C# is zoiezo wat moeilijker omdat data gescheiden moet blijven om typesafe te zijn.

anyway pseudocode:

[cpp]
void *mijnpoint;
mijnfunctie (a,b,&mijnpoint);
squarepointer squary = (squarepointer*) mijnpoint

int mijnfunctie(int *a, int *b, void **pointer)
{
*pointer = anderepointer
}
[/cpp]

Maar een gecaste pointer-to-pointer werkt waarschijnlijk ook
 
dat was ik idd in c# testprojectje vergeten (vb was ByRef in c# ref / out dachtk ) xD.

Bedankt wederom voor de info, ik zal eens een poging wagen!
 
Whao, heb het eindelijk voor elkaar gekregen. via de void manier die je aankaartte lukte het mij niet alleen het principe daarvan lukte wel (kennis ontbreekt wat dat betreft, heb nog nooit met "void objecten" gewerkt op returntypes na)

[cpp]

void functie()
{
SquareObject *pointer = 0;

//verder gebruik van pointer.

}

void method(SquareObject **pointer)
{

*pointer = concreteClassSquareObjectPointer;
//gebruik van de pointer dmv (*pointer)->[functies van squareObject]
}


[/cpp]
 
Laatst bewerkt:
Goed om te horen dat het gelukt is. Void pointer is niet zo heel veel anders, maar moet je casten voordat je hem weer terug kan gebruiken. Daar je de pointer in de eerdere functie niet in de functie zelf gebruikte was casten binnen de functie niet nodig. Vandaar dat mijn voorbeeld alleen teruggeven pointer via een cast terug gaf.

Het voordeel van een voidpointer is dat het een pointer naar elke willekeurige andere pointer mag zijn. Als je dus, bijvoorbeeld een discrete waarde of een array terug wil geven met dezelfde funtie kan dat met een void pointer. Natuurlijk moet je dan wel ook de juiste manier van casten dan weer teruggeven naar de aanroepende functie.

Vaak is een pointer to pointer van een specifiek type veiliger, maar void pointers hebben hun waarde bij het gebruik van streams en iterators.
 
Nooit gedacht toen ik met c++ begon dat ik al zo snel tegen een pointer-pointer aan zou lopen, zag dat meer als iet geavanceerd maarja blijkbaar valt dat opzich ook wel mee.
Bedankt voor de hulp wederom, zal je tip onthouden over de void pointer.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan