Sinn von Zeigern und Referenzen
-
cout << "Es wurde " << textSize << " Byte Speicherplatz reserviert.\n"
Um die anzahl der bytes zu ermitteln muss diese zeile so aussehen
cout << "Es wurde " <<(sizeof(textSize)) << " Byte Speicherplatz reserviert.\n"
-
Hallo,
mit
cout << "Es wurde " << textSize << " Byte Speicherplatz reserviert.\n";
gibst du lediglich die Startadresse aus, an der der reservierte Speicherbereich
beginnt. Du gibst aber nicht aus, wieviel Speicher du reserviert hast. Gib dazu
doch einfach 'chars' aus.Das Reservieren hast du korrekt gemacht, was du aber nicht gemacht hast, ist den
Speicher wiederfreizugeben. Dir fehlt am Schluss noch eindelete[] textSize;
Denk immer daran: Den Speicher, den du reservierst, musst du auch wieder frei-
geben.mfg
v R
-
pin schrieb:
cout << "Es wurde " << textSize << " Byte Speicherplatz reserviert.\n"
Um die anzahl der bytes zu ermitteln muss diese zeile so aussehen
cout << "Es wurde " <<(sizeof(textSize)) << " Byte Speicherplatz reserviert.\n"
Nein, dass gibt dir nur die Groesse des Zeigers aus, nicht aber die Anzahl
reservierter Bytes.mfg
v R
-
pin schrieb:
Um die anzahl der bytes zu ermitteln muss diese zeile so aussehen
out << "Es wurde " <<(sizeof(textSize)) << " Byte Speicherplatz reserviert.\n"sizeof auf nen zeiger anewandt ergibt bei mir immer 4. und das ist ja ein zeiger. wäre es ein array, wäre das was anderes, da klapt sizeof (,solange man es nicht innerhalb einer funktion macht und das array übergeben wurde, denn dabei hat der compiler es heimlich zu nem zeiger zusammen und sizeof decjt das dann auf).
-
Stimmt mein Programm nun, oder muss ich noch plus ein Byte rechnen (wegen Stringende-Zeichen)?
Caipi
#include <iostream> using namespace std; int main() { cout << "Bitte Text eingeben:\n"; int chars = 0; char character; while(cin.get(character) && character != '\n') { chars++; } char *textSize = new char[chars]; cout << "Es wurde(n) " << 1 * chars << " Byte Speicherplatz reserviert.\n"; delete[] textSize; return 0; }
-
Stimmt du hast recht es ergibt immer 4 Byte das wusste ich jetzt aber auch nicht gut danke dir.
Nur jetzt hab ich folgendes Problem festgestellt. Wenn ich bei mir das Prog laufen lasse sollte folgende zeile ja die anfangsadresse des Zeigers anzeigen.
cout << "Es wurde " <<textSize << " Byte Speicherplatz reserviert.\n";
Aber bei mir tut es nicht. Nur wenn ich auf die C schreibweise überspringe
printf("\n\nDie anfang der Adresse von TextSize ist:\t%p",textSize);
klappt dies weist du warum das so ist?
Kann man in cpp auch mit Platzhaltern arbeiten bei der ausgabe (%i,%f,%p,%u)... oder so?
-
Caipi schrieb:
Stimmt mein Programm nun, oder muss ich noch plus ein Byte rechnen (wegen Stringende-Zeichen)?
Caipi
#include <iostream> using namespace std; int main() { cout << "Bitte Text eingeben:\n"; int chars = 0; char character; while(cin.get(character) && character != '\n') { chars++; } char *textSize = new char[chars]; cout << "Es wurde(n) " << 1 * chars << " Byte Speicherplatz reserviert.\n"; delete[] textSize; return 0; }
Dein Programm tut ja nichts. So wie du es jetzt eingetippt hast, ist es korrekt.
Auf das Nullterminierungszeichen und das damit verbundene "mehrreservieren von
1 Byte" musst du eigentlich nur in Situationen folgender Art beachten:void just_an_example(char *cstring) { char *cpy_of_cstring = new char[strlen(cstring)+1]; //+1 wegen \0 //...irgendwas }
Wenn du natuerlich weisst, dass dein Array 80 Zeichen aufnehmen soll, musst du
fuer 81 Zeichen Speicher reservieren, damit der C-String auch ordentlich mittels
Nullterminierungszeichen abgeschlossen werden kann.Anstelle von C-Strings solltest du dir jedoch angewoehnen, die string-Klasse
einzusetzen (ich wollts nur erwaehnt haben, bevor jetzt jeder auf mich ein-
schlaegt ;)).mfg
v R
-
Vielen Dank virtuell Realisticer!
Jetzt aber noch eine letzte Frage:
Wie kann ich Speicher dynamisch reservieren, wenn ich einen Text von der Laenge n eingebe und gleichzeitig der eingegebene Text an den dynamisch reservierten Speicher übergeben wird. Geht das?Ich habe es schon versucht, bisher erfolglos
Caipi
-
Caipi schrieb:
Ich habe es schon versucht, bisher erfolglos
kein wunder. es ist nicht einfach.
üblich ist folgendes:
du schätzrt erstmal, daß 10 zeichen reichen (incl. der 0) werden, legst also new char[10] an. die machte dann auch zeichen für zeichen voll. wenn beim vollmachen irgendwann festgestellt wird, daß die 10 plätze nicht reichen, machste schnell mit new char[20] nen größeren bereich frei und kopierst die bisher eingegebenen zeichen in den größeren bereich und gibst den alten kleinen bereich mit delete[] frei. dann tuste weiter zeichen einlesen. bis endlich das '\n' kommt. naja, vielleicht wird der neue bereich auch voll bevor '\n' kommt. ist ja nicht schlimm, dann legste einfach mit new char[40] nen nochmal größeren bereich an, kopierst um, löscht und weiter geht's.
läßt sich in ne hübsche schleife packen das, wenn man nen tag oder zwei zeit hat.
viel spaß.
-
Das ist so natuerlich erstmal nicht moeglich. Wenn du zur Zeit der Eingabe noch
nicht weisst, wie gross n sein wird, kannst du natuerlich auch nicht n-Byte
Speicher reservieren.In einem solchen Fall geht man hin und reserviert Speicher fuer eine bestimmte
Anzahl Bytes. Ist der Text groesser als der reservierte Speicherbereich,
reserviert man einen neuen Speicherbereich, der etwas groesser als der alte ist,
kopiert den alten Speicherbereich in den neuen und fuegt die Zeichen, welche
mehr da sind, dem neuen Speicherbereich an. Das geht dann natuerlich immer so
weiter.Daher meine Anregung, dich mal mit der string-Klasse auseinanderzusetzen.
Zusaetzlich benoetigst du dann auch noch die vector-Klasse. vector ist quasi das
STL-pendant zu einem C-Array und kann z. B. so eingesetzt werden:#include <iostream> #include <vector> using namespace std; //namensraum oeffnen; wir ersparen uns dann std::vector int main() { vector<int> myVec; //vector mit 0 elementen (leerer vector) vector<int> myVec2(5); //vector mit 5 elementen vector<int> myVec3(5, 0); //vector mit 5 elementen, initialisiert mit 0 vector<int> myVec4(myVec2); //vector initialisiert mit myVec2 /* mit der push_back-Memberfunktion wird ein wert in den vector aufgenommen. Um den Speicherbereich, brauch man sich hier nicht zu kuemmern, das ist Aufgabe des vectors */ for(size_t i = 0; i < 5; ++i) { myVec.push_back(i); myVec2.push_back(i); myVec3.push_back(i); myVec4.push_back(i); } cout<<myVec[2]<<endl; //Ausgabe des 3ten Elements in myVec myVec[2] = 5; //3tes Element in myVec hat jetzt den Wert 5 return 0; //den Speicherbereich, den die vectoren belegen, werden beim //Zerstoeren der vector-Objekte wieder freigegeben }
Und diese vector-Klasse kannst du auch dafuer nutzen, um, theoretisch, Text
einer beliebigen groesse zu Speichern:#include <iostream> #include <string> #include <vector> using namespace std; int main() { string currentLine; //aktuelle zeile, die gelesen wird vector<string> content; //alle zeilen, die gelesen wurden while(getline(cin, currentLine)) //so lange von stdin gelesen werden kann content.push_back(content); //zeilen in content speichern //ausgabe des inhaltes for(size_t i = 0; i < content.size(); ++i) cout<<content[i]<<"\n"; return 0; }
Wie du siehst, ist es hier nicht noetig sich per Hand um die Speicher-
reservierung zu kuemmern. Das tut unsere vector-Klasse und somit kann es auch
nicht vorkommen, dass wir vergessen Speicher freizugeben und somit ist schonmal
diese Fehlerquelle beseitigt.Hoffe das hat dir was weitergeholfen.
mfg
v R
-
Vilen Dank euch allen!
Caipi