Speicherreservierung per Funktion nicht erlaubt?
-
Hallo.
Ich versuche mal anhand einer kurzen Beschreibung mein Problem zu schildern.
Mein Programm startet mit einem simplen Zeiger.
Dieser Zeiger wird per Referenz an eine Funktion tu_etwas() übergeben.
In der Funktion tu_etwas() wird für den Zeiger ein 10 mal String großes Array an Speicherplatz reserviert.
Anschließend wird in jedes einzelne der 10 Arrayfelder das Wort "Ax" (x steht für eine Zahl) geschrieben.
Gehen wir nun zurück in die main() und versuchen das erste Arrayfeld [0] des Zeigers auszugeben, bricht das komplette Stück mit Speicherfehlern zusammen.
Ich kann genau so wenig in der main() die Anzahl der reservierten Felder mit sizeof() zählen.
Hat jemand eine Idee, wieso nicht?
Hier eben der Quellcode:
void tu_etwas( string *zeigerArray ) { zeigerArray = new string[10]; for( int i = 0; i < 10; i++ ) zeigerArray[i] = "A" + i; } int main( void ) { string *zeiger = 0; tu_etwas( zeiger ); cout << zeiger[0]; cin.get(); return 0; }Lieben Gruß, paSe
-
Wenn du das willst, dann brauchst du entweder einen Pointer auf einen Pointer oder eine Referenz auf einen Pointer.
Es wird ja nur der lokale Pointer in der Funktion verändert, aber der Pointer im Hauptprogramm bleibt ja unverändert, denn der Pointer selbst wird per Call By Value übergeben.
-
sieht iwie doch bissl nach C aus - abgesehen von std::string (den namespace errate ich jz einfach mal so ^^)
void tu_etwas( string &*zeigerArray ) //referenz auf den Zeiger, weil { zeigerArray = new string[10]; //hier der Zeiger eine neue (andere) Adresse zugewiesen bekommt for( int i = 0; i < 10; i++ ) zeigerArray[i] = "A" + i; //das hier ist bestimmt nicht, was du dir vorstellst... weiß auch nicht genau, wieso das so durch den Compiler gehen sollte :P } int main () //void wird in C++ üblicherweise nicht in die Parameterliste geschrieben { string *zeiger = 0; tu_etwas( zeiger ); cout << zeiger[0]; cin.get(); delete[] zeiger; //! // return 0; unnötig }das gleiche in C++:
#include <string> #include <vector> #include <iostream> void tu_etwas(std::vector <std::string> &arr) { for( char i = 0; i != 10; ++i ) //mit "int", "<" und "i++" wärs auch gegangen, aber dann hättest du beim '0' + i mit sicherheit ne warning bekommen { std::string toAdd = "A"; toAdd.push_back ('0' + i); arr.push_back (toAdd); } } int main () { std::vector <std::string> arr; tu_etwas( arr ); cout << arr[0] << "..." << arr[9]; //zugriffe ganz normal, wie auch bei deinem array cin.get(); // delete[] zeiger; //brauchen wir jetzt nicht mehr - können wir also auch nicht versehentlich vergessen ^^ }oder brauchtest du den pointer unbedingt?
falls ja: es ist doof, in irgend ner Funktion nen new/new[] ohne delete/delete[] zu haben... also biete entweder noch ne funktion an, die das konstrukt da wieder freigibt, oder verlager das new auf außerhalb die funktion...
oder aber, nimm eine klasse und schreibe dir nen entsprechenden CTor + DTor...ich hoffe, du verstehst einigermaßen, was ich versucht habe, zu erklären ^^
falls nicht, dann frag eben einfach nach, falls du irgendwas grundlegendes nicht verstanden hast (und sag dabei, was du denn kannst und seit wann/wie/... du C++ lernst) - wenns nur ne einzelne Funktion ist:
http://www.cplusplus.com/reference/
http://www.cppreference.com/wiki/
auf den beiden Seiten hast du eigentlich ne wunderschöne Auflistung der STL und ne kurze Erklärung zu den Fkt und meist auch noch nen kleines Bsp. dabei...bb
-
Dass ich freigegebene Speicherreservierungen wieder löschen muss, damit der RAM nicht zugeschüttet wird, ist mir durchaus bewusst.
Falls es nicht deutlich geworden ist, möchte ich kurz betonen, dass dies ein simples Beispiel war, um Quelltext zu sparen und es bündig zu halten ohne meine restlichen zweihundert Zeilen meiner Klassenmethode zu posten, sodass jeder erst mal nachvollziehen darf, was meine Methode machen soll obwohl mein eigentliches Problem ja nur einen kurzen Ausschnitt umfasst.
Das ist beispielsweise auch der Grund, weshalb ich die Library Files und das Namespace weggelassen habe.
Vielen Dank mit der Erklärung "Pointer auf Pointer".
Irgendwo logisch - bin leider nicht selber drauf gekommen.
Lieben Gruß, paSe.
-
So gern ich früher auch immer ** in Funktionen hatte, wo ich den Speicher selbst allokieren musste...
Heute mache ich das auch so wie unskilled das vorschlägt. Entweder den Speicher außerhalb allokieren und dann an die Funktion übergeben, oder einfach eine Referenz ( oder einen Pointer ) auf einen Vektor an die Funktion übergeben und schon gibt es keine Probleme mehr. Manches ist an C++ einfach viel schöner.
Früher in C... wo die Funktionen bei mir voller '*' waren.. *grusel*
Denn beim Zugriff auf ein solches Konstrukt in der Funktion musst du dann auch auf die '*' achten.
void tu_etwas( string **zeigerArray ) { zeigerArray = new string[10]; for( int i = 0; i < 10; i++ ) (*zeigerArray)[i] = "A" + i; }... wenn ich mich recht entsinne... lang lang ists her

Ergo: Viele '*' machen den Quelltext nicht unbedingt schöner... wobei es in dem Fall gerade so noch geht

-
it0101@loggedoff schrieb:
Früher in C... wo die Funktionen bei mir voller '*' waren.. *grusel*
Denn beim Zugriff auf ein solches Konstrukt in der Funktion musst du dann auch auf die '*' achten.
Also wenn du nur Angst vor Sternchen hast, übergib doch eine Referenz auf einen Pointer:
void tu_etwas( string *& zeigerArray ) { zeigerArray = new string[10]; // in deinem Code fehlt hier übrigens ein * for( int i = 0; i < 10; i++ ) zeigerArray[i] = "A" + i; }
-
oder so

Aber in dem Fall empfinde ich den vector<T> als elegantere Lösung ( und heutzutage würde ich das sogar so machen
)