Lesen aus ini funzt nicht...



  • Kann mir jemand sagen wo der Fehler ist? Die Funktion gibt nur die ersten 4 Zeichen korrekt aus und der Rest ergibt nur Müll.

    PSTR ReadIni(PSTR path, PSTR entry)
    {
    	char buffer[500]; 
    
    	DWORD size; 
    	size=500; 
    
    	GetPrivateProfileString(path,entry,"NULL",buffer,size,file); 	return buffer;
    }
    

    (file wird woanders definiert - daran liegts net)



  • Hab das jetzt nicht ausprobiert, aber das das Null in Anführungstrichen steht und dann noch 4 Buchstaben hat, scheint mir sehr verdächtig 😉
    An dessen Stelle soll doch eigentlich ein ausreichend großer Speicherbereich übergeben werden, oder ? 😕

    Edit: Hab mir die Doku nochmal angeschaut, scheint wohl doch richtig so zu sein, obwohl er bei Me/98/95 doch verändert wird trotz seiner Constant-Deklaration.



  • Du wirst es nicht glauben, aber das war auch meine erste Idee 😉 , hat aber nichts damit zu tun, weil das nur der default Wert ist, der zurück gegeben wird, wenn der Eintrag nicht gelesen werden kann.
    Ich habs jetzt grad aber hinbekommen. Ich weiß zwar nicht wo jetzt genau der Unterschied ist (hab das buffer Array einfach auf dem Heap erzeugt), aber jetzt geht es...

    PSTR ReadIni(PSTR path, PSTR entry)
    {
    	char* pPoint;
    	pPoint = new char[500]; 
    
    	DWORD size; 
    	size=500; 
    
    	GetPrivateProfileString(path,entry,"NULL",pPoint,size,file); 	return pPoint;
    }
    


  • Jetzt wo du das schreibst fällt es mir wie Schuppen vor die Augen:

    Der char* pPoint; wird doch wieder freigegeben, wenn du die Funktion verlässt.

    Passiert mir auch alle Jahre wieder 😉



  • Aber wird denn auch jetzt der Platz auf dem Heap wieder freigegeben?



  • 5(0rP schrieb:

    Aber wird denn auch jetzt der Platz auf dem Heap wieder freigegeben?

    Nein, das ist ja das Gefährliche.
    Es ensteht ein MemoryLeak, wenn du den zurückgelieferten Pointer auf den String nicht wieder freigibst.

    Aber Achtung, dass du mit delete auch das ganze Array wieder frei gibst, und nicht den Pointer selber. (An die [] beim delete denken!!! )



  • Aber wie soll ich denn nach dem return noch einen delete einbauen? Die Funktion ist doch dann zuende.

    Hmm Ich denke mal das beste wäre den Pointer global (innerhalb von meiner Klasse) zu definieren. Dann kann ich den Speicher wiederverwenden.



  • Den Speicher sollst du auch erst freigeben, nachdem die Funktion aufgerufen wurde. So:

    LPSTR *pstr= ReadIni(path, entry);
    //[...pstr verarbeiten...]
    delete[] pstr;
    

    da ist es aber wohl schöner, wenn du der Funktion gleich zwei weitere Parameter LPSTR (Adresse wo der String hin soll) und DWORD (maximale Länge vom zu lesenden String)gibst und der aufrufende Code selbst den Speicher organisiert.

    Die Idee mit der Klasse ist eher schlecht, da du nur solange den String benutzten kannst, bis die Funktion nochmal aufgerufen wird (mehrere Threads können ohne Synchronisation auch nicht auf die selbe Instanz zugreifen).



  • Mit Threads arbeite sowieso noch net so viel. Damit kenn ich mich noch nicht aus.

    Ich hab das ganze jetzt so gemacht, dass der Speicher im Destruktor meiner Klasse freigegeben wird.

    In der Funktion weiß ich net wie ich das machen soll. Ich muss den String ja mit return zurückgeben und nach return kann ich ja schlecht noch einen Befehl zum Freigeben des Heap Speichers einbauen, weil die Funktion zuende ist. Oda gibts doch ne Möglichkeit 😕



  • Eben die, die D@niel $chumann schon gesagt hatte - als Aufrufen Speicher reserierven und dann der Funktion nur den Pointer auf den Speicherbereich mit der Länge übergeben.

    Dein erster Code funktioniert übrigens aus genau diesem Grund nicht, da beim Verlassen des Gültigkeitsbereichs auch der Speicher von Buffer ungültig wird / werden kann 😉



  • Ach sooooo... Jetzt hab ichs kapiert. Naja, dauert halt manchmal n bissl länger. Thx, werd ich morgen mal ausprobieren. 💡


Anmelden zum Antworten