Loeschen von Arrays im Destruktor
-
Gast-1 schrieb:
Warum? Das kommt darauf an was ich damit machen will und ist aus diesem Beispiel nicht ersichtlich. Will ich das Array auch mal ändern macht const keinen Sinn.
String-Literale sind const (daß du mit einem nicht-konstanten Zeiger darauf verweisen darfst, hat etwas mit Abwärtskompatibilität zu tun), da löst du nur eine Schutzverletzung aus, wenn du dieses Array ändern willst.
Wenn du etwas wirklich änderbares haben willst, mußt du selber den Speicher bereitstellen:
class Test { char array[10]; public: Test() { strcpy(array,"12345"); } }; //oder class Test { char*array; public: Test() : array(new char[10]) { strcpy(array,"12345"); } ~Test() { delete[]array; } };(die letzte Variante braucht noch Copy-Construktor und op=)
Oder du verwendest gleich C++ Bordmittel - std::string oder std::vector<>.
Gast-1 schrieb:
*char ist ja auch ein Array oder schaut der Compiler nach dem new[] mit den Klammern und meckert dann wenn ich delete[] verwende, weil ich eben new *char benutzt habe und nicht new char[]?
In dem Zusammenhang ist '*char' kein Array, sondern ein Zeiger - da würde der Compiler schon meckern, wenn du dessen Adresse im falschen Datentyp unterbringen willst.
-
Also gut dann sieht meine Klasse so aus: Die Klasse soll einen Text
in einem char-Array aufnehmen und les und schreibbar sein:class Test { private: char *array; public: Test(char *c) { array=c; } *char getText() const { return array; } void setText(const char *c) const { array = c }; ~Test() { //Was steht hier? } };Mit "12345" legst Du schon zur Compilezeit Speicher an. Den kannst Du nicht mehr zur Laufzeit ändern, Löschen, ....
Achso, wusste ich nicht dass der nicht mehr änderbar ist.
Mit char* array = "12345";
drückst Du aus, dass Du einen Zeiger namens array auf diesen Speicherbereich zeigen lassen willst UND sowohl den Zeiger auf etwas anderes zeigen lassen , als auch den Wert, auf den er zeigt, ändern können willst.Ich dachte char *array = "12345";
ist das selbe wie char[] = "12345";
-
Also deine Klasse kann so nicht funktionieren - in der Methode setText() sind die const's zu viel.
(btw, char*a und char a[] sind nicht identisch - ersterer deklariert einen Zeiger auf (normalerweise) fremde Speicherbereiche, letzterer legt selber einen entsprechend großen Speicherblock an)
-
Hi!
*char getText() constDa is ein Syntaxfehler, der Stern is falsch gesetzt.
~Test() { //Was steht hier? }Garnix steht da...
grüße
-
CStoll schrieb:
//oder class Test { char*array; public: Test() : array(new char[10]) { strcpy(array,"12345"); } ~Test() { delete[]array; } };(die letzte Variante braucht noch Copy-Construktor und op=)
Genau sowas meinte ich, danke.
Das mit den Zeigern und Arrays (genauer char arrays) bereitet mir immer noch Probleme.Oder du verwendest gleich C++ Bordmittel - std::string oder std::vector<>.
Ja, klar aber das mit den Arrays und den Zeigern darauf und im Zusammenahng mit Klassen sollte man trotzdem kapieren, deshalb meine Frage hier ins Forum.
Ich muss mal wieder die entsprechenden Kapitel in meinen Büchern durcharbeiten, ist lange her, als ich mit C++ zu tun hatte und das damals auch nur sporadisch, wie man unschwer an meinen dilettantischen Fragen erkennen konnte

Danke an euch.
-
CStoll schrieb:
Also deine Klasse kann so nicht funktionieren - in der Methode setText() sind die const's zu viel.
Stimmt, sonst wäre es nicht änderbar.
Und der der Stern in getText() ist auch falsch, war ein Vertipper.
(btw, char*a und char a[] sind nicht identisch - ersterer deklariert einen Zeiger auf (normalerweise) fremde Speicherbereiche, letzterer legt selber einen entsprechend großen Speicherblock an)
Ja, das muss ich nochmal in Ruhe nachlesen, das muss man sicher beherrschen, sonst wird das nix mit einem funktionierenden Programm.
-
Gast-1 schrieb:
...
Das mit den ... char arrays ...bereitet mir immer noch Probleme.
...Da das allen so geht, wurden ja Hilfsmittel wie string und die STL-Container geschrieben.

Aber es ist natürlich löblich, sich um korrektes Ressourcenhandling zu kümmern. Leider gibt's da keinen "Globalfall", sondern man muß für sich bei der Modellierung jedesmal wieder neu Gedanken darüber machen, wem jetzt eigentlich was gehört (und der ist dann für das Erzeugen und Löschen verantwortlich - im Idealfall).BTW:
CStoll schrieb:
...
(btw, char*a und char a[] sind nicht identisch - ersterer deklariert einen Zeiger auf (normalerweise) fremde Speicherbereiche, letzterer legt selber einen entsprechend großen Speicherblock an)Ich denke, er meinte eine Deklaration wie:
char const *a1 = "12345"; char const a2[] = "67890";In dem Zusammenhang ist das schon (im Wesentlichen) "dasselbe" (zumindestens kann man a1 und a2 identisch verwenden).
Gruß,
Simon2.
-
Simon2 schrieb:
In dem Zusammenhang ist das schon (im Wesentlichen) "dasselbe" (zumindestens kann man a1 und a2 identisch verwenden).
cout << sizeof(a1) << endl; cout << sizeof(a2) << endl;Nope.

-
LordJaxom schrieb:
Simon2 schrieb:
In dem Zusammenhang ist das schon (im Wesentlichen) "dasselbe" (zumindestens kann man a1 und a2 identisch verwenden).
cout << sizeof(a1) << endl; cout << sizeof(a2) << endl;Interessant was man hier alles erfährt ich glaube ich sollte mir mal ein neues Buch kaufen. Was empfehlt ihr denn als zeitgemässes Werk das auch solche C-Stolperfallen enthält oder sollte man sich dafür ein separates C-Buch kaufen? Dieses Zeigergewurschtel hat ja eigentlich nichts mit C++ zu tun.
-
LordJaxom schrieb:
Simon2 schrieb:
In dem Zusammenhang ist das schon (im Wesentlichen) "dasselbe" (zumindestens kann man a1 und a2 identisch verwenden).
cout << sizeof(a1) << endl; cout << sizeof(a2) << endl;Nope.

Mir ist das schon klar, dass es nicht dasselbe ist....
Deshalb mein "im Wesentlichen" und die Anführungszeichen um "dasselbe" .... damit meinte ich die Dinge, die unser Gast damit machen möchte: Zugreifen auf die Dateninhalte, Index-Verwendung, Pointerarithmetik, Allokationsverantwortung (ja, ich weiß, dass der Compiler dabei zwischen [] und * unterscheidet), ....
und wenn ich recht informiert bin, legtchar const array[] = "12345";nicht mehr den Speicher an als
char const *array = "12345";... was aber CStolls Grundbehauptung war.

Gast-1 schrieb:
...sollte man sich dafür ein separates C-Buch kaufen? Dieses Zeigergewurschtel hat ja eigentlich nichts mit C++ zu tun.
Ich würde trotzdem ein C++-Buch vorziehen, weil da doch ein paar "Kleinigkeiten" anders laufen.
Leider kann ich Dir dazu kein spezielles Werk empfehlen, weil ich mir selbst so'n Zeug aus unterschiedlichen Quellen zusammenklaube (aber für mich ist "Die C++-Programmiersprache" von Stroustrup - aktuellste Ausgabe - ein wichtiger Ausgangspunkt).Gruß,
Simon2.
-
Simon2 schrieb:
Mir ist das schon klar, dass es nicht dasselbe ist....
Deshalb mein "im Wesentlichen" und die Anführungszeichen um "dasselbe" ....<spitzfindig> In der Klammer schreibst Du aber ohne Einschränkung und Anführungszeichen "identisch" </spitzfindig>
und wenn ich recht informiert bin, legt
char const array[] = "12345";nicht mehr den Speicher an als
char const *array = "12345";... was aber CStolls Grundbehauptung war.

Wie ist der Satz zu verstehen? Wenn Du meinst, dass er in beiden Fällen keinen Heap-Speicher allokiert, hast Du recht. Im Sinne von "Speicher anlegen" wird aber die erste Variante (wenn in einer Funktion) auf dem Stack angelegt, bei der zweiten liegt der Text in irgendeinem (potentiell read-only) Datenbereich.
-
LordJaxom schrieb:
...
<spitzfindig> In der Klammer schreibst Du aber ohne Einschränkung und Anführungszeichen "identisch" </spitzfindig>
Hi,
Wenn schon spitzfindig, dann richtig: Da
cout << a1; cout << a2;beide verwendbar sind, kann ich sie "identisch verwenden" (vielleicht nicht in jedem Zusammenhang, aber das habe ich ja auch nicht behauptet). :p

Aber lass uns das mal beiseite legen.LordJaxom schrieb:
...
...wird aber die erste Variante (wenn in einer Funktion) auf dem Stack angelegt, ...EDIT: Hab's schon gefunden:
http://c-faq.com/aryptr/
bzw. direkt:
http://c-faq.com/aryptr/aryptr2.htmlGruß,
Simon2.
-
char const array[] = "1234";Dies legt implizit ein Array der Größe 5 an und kopiert den String (+abschl. Null-Zeichen) in das Array.
-
Th schrieb:
char const array[] = "1234";Dies legt implizit ein Array der Größe 5 an und kopiert den String (+abschl. Null-Zeichen) in das Array.
Was aber auch bedeutet, dass die Poinervariante const sein muss, während die []-Variante auch non-const sein darf ....
Gruß,
Simon2.
-
Da hast du völlig recht, auch wenn Compilerhersteller das bisweilen anders sehen (was die const-correctness anbelangt)

Tatsächlich darf ein Programm abstürzen, wenn man bei der Pointervariante am String herummanipuliert. (Page Fault auf einer Read-Only Page wäre z.B. denkbar)