frage zu strings bzw char *
-
danke für deine antwort
tommie-lie schrieb:
... Es wird also durch die Zuweisung selbst kein Speicher reserviert, weil das bereits beim Starten des Programmes geschehen ist.
heisst das, dass alle varianten des strings irgendwo den speicher "vollstopfen", selbst wenn vielleicht nur eine zur laufzeit je verwendet wird?
gibt es dann vielleicht auch eine elegantere methode mit strings umzugehen? also dass immer nur der speicher, der gerade tatsächlich benötigt ist angefordert wird. oder ist es müßig sich darüber sosehr den kopf zu zerbrechen?
-
Die einzige Möglichkeit, dass konstante Strings nicht irgendwo im Programmcode rumliegen, ist es sie in eine Datei (bzw. sonstige externe Stelle) auszulagern. Hat aber wenig Sinn, wenn es nicht sehr viele sind.
MfG SideWinder
-
Eine weitere Möglichkeit unter Windows wäre eine STRINGTABLE-Ressource. Dies sei jedoch nur der Vollständigkeithalber erwähnt.
Greetz, Swordfish
-
[quote="jule37"]
char *MeinString; /* je nachdem entweder */ MeinString = "Informationstext 1\0"; /* oder */ MeinString = "Informationstext alternative...\0";
Hi jule,
das dies funktioniert lieget daran das "Informationstext 1\0" und "Informationstext alternative...\0" Literale sind und beim Start des Programms automatisch Speicher dafür allokiert wird. Wenn du unter Linux arbeitest und einen strings auf das übersetzte Programm machst, dann wirst du die Texte auch wieder finden.Mit MeinString zeigst du nur auf die zuvor beim start allokierten speicherberreiche bzw. biegst den Zeiger eben auf einen anderne um.
Natürlich kannst du es weiterverwenden, solange du du den vordefinierten Text (im Quellcode) nicht im selben Speicherbereich ändern willst.
greetz
codefrag
-
jule37 schrieb:
heisst das, dass alle varianten des strings irgendwo den speicher "vollstopfen", selbst wenn vielleicht nur eine zur laufzeit je verwendet wird?
"Vollstopfen" ist bei den Größenordnungen lustig. Wieviele Stringliterale hast du im Quellcode? Ein Kilobyte? Und wie groß ist der Rest des Programmes im Vergleich dazu? Siehste?
Nur den Speicher für tatsächlich benutzte Strings zu allokieren wird nicht klappen. Die Strings müssen irgendwo gespeichert werden, falls sie doch verwendet werden. Da ist es doch schon elegant, daß nicht bei der Zuweisung nochmals Speicher auf dem Heap (über malloc()) allokiert wird und der String aus der Ausführbaren Datei dorthin kopiert wird, sondern der schon vorhandene Speicherbereich benutzt wird. Woher soll denn der Compiler zur Kompilierungszeit wissen, welche Strings beim Aufruf des Programmes benötigt werden.
Stell dir vor, du hast ein Programm, daß einen Kommandozeilenparameter annimmt und je nach Wert dieses Parameters unterschiedliche Strings ausgibt. Der Compiler kann nicht wissen, mit welchem Parameter du später das Programm aufrufen wirst, also muss er alle Strings mit in das Programm packen.
Jeder String, den du im Quellcode verwendest (unabhängig davon, ob er später zur Laufzeit verwendet wird), landet auch im Programm und wird später beim Ausführen in den Speicher geladen. Das liegt in der Natur moderner Systeme, die nicht während der Ausführung Befehl für Befehl in den Speicher laden, sondern das Programm einmal vollständig in den Speicher laden.jule37 schrieb:
oder ist es müßig sich darüber sosehr den kopf zu zerbrechen?
Ja, ist es. Wenn dein Programm optimieren willst, tue das an anderen Stellen.
Swordfish schrieb:
Eine weitere Möglichkeit unter Windows wäre eine STRINGTABLE-Ressource. Dies sei jedoch nur der Vollständigkeithalber erwähnt.
Ressourcen sind unter Windows Teil des Images und werden somit auch zusammen mit dem Programm in den Speicher geladen. Der Vorteil von Stringressourcen ist die einfache Veränderbarkeit ohne Neukompilation. Aber die erkauft man sich damit, daß man für jede Stringzuweisung Funktionen aufrufen muss, die den String aus der Ressource laden. Und selbst wenn man die Ressource in eine Ressourcen-DLL steckt und die erst bei Bedarf lädt, werden beim Bedarf alle Strings auf einmal in den Speicher geladen, womit man wieder am Anfang steht.
-
Sind eher zur Internationalisierung, etc. gedacht. Da kann man dann sehr schnell ein ResourceBundle "en" durch eins mit dem Namen "de" austauschen
MfG SideWinder
-
Hallo ich hätte hier auch eine Frage zur Speicherverwaltung
const char* createStringPointer() { char* mystring = "This is my string"; return mystring; } int main() { const char* r_string = createStringPointer(); printf("%s\n",r_string); exit(0); }
Ich verstehe nicht genau warum das was ich da geschrieben habe überhaupt
funktioniert! Wird hier Speicher auf dem Heap reserviert obwohl ich kein malloc
gemacht habe? Warum funktionert der printf überhaupt? Wo geht mystring out of scope?
Evt überhaupt nicht?
-
xauser schrieb:
Ich verstehe nicht genau warum das was ich da geschrieben habe überhaupt
funktioniert! Wird hier Speicher auf dem Heap reserviert obwohl ich kein malloc
gemacht habe? Warum funktionert der printf überhaupt? Wo geht mystring out of scope?
Evt überhaupt nicht?Ja da du ein Stringliteral benutzt, für das zum Programmstart automatisch Speicher allokiert wird.
Genauer wie es funktioniert ist hier:
http://home.fhtw-berlin.de/~junghans/cref/CONCEPT/string.htmlgreetz
der codefrag
-
Nein, in deinem Beispiel wird kein Speicher auf dem Heap reserviert. Der Compiler legt den Zeichenkettenliteral "This is my string" in deiner .exe ab. Mit
char* mystring = "This is my string";
lädst du lediglich die Adresse der Zeichenkette in mystring und in weiterer Folge mit
const char* r_string = createStringPointer();
nach r_string. printf( ) gibt diesen dann aus.
BTW: Der Aufruf von exit( ) am ende von main( ) ist für die Katz.
Greetz, Swordfish
-
- Es wird kein Speicher auf dem Heap reserviert
- Die Zeichenfolge "This is my string" existiert bereits im .exe-File
- Der Scope von mystring selbst (4 Bytes) endet nach Beendigung der Funktion
- Es wird nur die Adresse des existierenden "This is my string" zurügereichtDe Facto (nach Compiler-Optimierung) ist die Funktion äquivalent zu
const char* createStringPointer() {return "This is my String";}
BTW: Es ist ein char-Pointer, kein Stringpointer.
Ein String ist bereits ein char-Pointer.