Hilfe bei Pointern und Dynamischen Speicher
-
buu2188 schrieb:
( das der Inhalt übernommen wird ist klar )
Ne, das ist nicht klar. Was heißt "übernehmen" für dich in diesem Fall? Das was Du wahrscheinlich als "Inhalt" verstehst (
"Darmstadt"
?) wird hier nicht kopiert.buu2188 schrieb:
[...] aber das die Adressen mit übernommen werden ist mir ein Rätsel ... Sind doch beide verschiedene Arrays?
Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein Pointer. Ein Pointer ist kein Array. Ein Array ist kein
buu2188 schrieb:
ist das Normal?
Ja.
Weder
name
nochm_name
in deinem Beispiel ist ein Array. Ein Array ist ein Speicherblock, dessen Größe zur Übersetzung des Programms bereits feststeht (und auch nachträglich nicht geändert werden kann). Arrays leben auf dem Stapelspeicher (Stack), Dynamisch reservierter Speicher jedoch auf dem Freispeicher (Heap).char* m_name; // Typ: char * (pointer to char) char* name = "Darmstadt"; // Typ: char * (pointer to char) 1) char foo[10]; // Typ: char[10] (array of 10 char) char bar[] = "Darmstadt"; // Typ: char[10] (array of 10 char)
- Eigentlich sollte
name
vom Typchar const *
(pointer to const char) sein, da er auf ein Zeichenkettenliteral zeigt. Zeichenkettenliterale dürfen zur Laufzeit nicht beschrieben werden und sind deshalbconst
.
Machst du nun
foo = bar
dann wird dir dein Lieblingscompiler sagen, daß du das nicht tun kannst. Arrays haben keine Kopiersemantik. Deshalb gibt esstd::copy
und Konsorten. Zu Fuß gehts eben mit einer Schleife.Machst du
m_name = name
so wird der Wert der Variablename
der Variablem_name
Zugewiesen. Dieser Wert ist eine Adresse - was auch sonst, beides sind schließlich Pointer. Beide Zeigen nach der Zuweisung auf den Anfang desselben Speicherbereichs. Der Speicherbereich, den du mitnew char[9]
(zu klein für"Darmstadt"
!!) reserviert hast, ist dir nach der Zuweisungm_name = name
nicht mehr Zugänglich, da du nirgends mehr die Adresse auf seinen Anfang gespeichert hast. Du kannst ihn weder verwenden noch jemals wieder ordentlich freigeben. Du hast ein Speicherleck.Das willst du aber wahrscheinlich nicht:
#include <cstring> #include <iostream> class foo_t { private: char const * m_name; public: foo_t( char const * name ) { m_name = name; // dont. do. this. } void print_name() const { std::cout << m_name << '\n'; // booom!?? } }; int main() { char * bar = new char[ 10 ]; std::strcpy( bar, "Darmstadt" ); foo_t foo{ bar }; foo.print_name(); // ok. delete[] bar; foo.print_name(); // BOOOOOOM!! }
Da der Speicherbereich auf den
bar
zeigt vor dem zweiten Aufruf vonprint_name()
freigegeben wurde, greift die Methode dann auf Speicher zu, der deinem Programm nicht mehr gehört. Das ist ein Fehler und fliegt dir früher oder später um die Ohren. Richtig wäre im Konstruktor einen ausreichend großen Speicherbereich anzufordern (new[]
) und die Zeichenkette, auf die der Parametername
zeigt dahin zu kopieren. Ob nun mit einer Schleife, mitstd::strcpy()
oderstd::copy()
läuft aufs selbe raus.
- Eigentlich sollte
-
was ist ein
char*
dann? Ich dachte es wäre das selbe wie
char[]
Ein Pointer auf das erste Element eines char?
Bitte mal mit einem c++ Anfängerbeispiel sowie der Herr auf der ersten Seite des Threads
Vielen Dank
-
char*
ist ein Pointer undchar[]
das Array. Das Array ist jedoch implizit in einen Pointer konvertierbar.char a[] = "hello"; char* p = a;
-
Swordfish schrieb:
Ein Array ist kein Pointer. Ein Pointer ist kein Array.
Ein Array ist nach der Definition in Größe und Lage unveränderlich.
Der Name vom Array alleine steht für die Anfangsadresse des Array.Einem Pointer kannst du jederzeit einen neuen Wert zuweisen, so dass er auf andere Speicherstellen verweist
Ein char[] als Funktionsparamter ist ein char*.
Aber: Ein Array ist kein Pointer. Ein Pointer ist kein Array.
char a[] = "hello"; char b[] = "world"; char* p = a; // p zeigt auf das h von "hello" p = b; // p zeigt auf w von "world" p++; // p zeigt auf o von "world", das Zeichen hinter w a = b; geht nicht a++; geht nicht sizeof(a) ergibt 6 (5 Buchstaben + '\0') sizeof(b) ergibt 6 sizeof(p) ergibt sizeof(char*), die Größe eines Pointers
-
Ahhh ok vielen Dank
Das heißt also wenn zBchar* irgendetwas = "Hallo";
Dann zeigt der Pointer auf die erste Speichersetelle und somit das "H"?
-
buu2188 schrieb:
char* irgendetwas = "Hallo";
Dann zeigt der Pointer auf die erste Speichersetelle und somit das "H"?
Ja, ja das heißt es.
Etwas genauer:
"1" ist ein Stringliteral, da wird automatisch die '\0' angehängt. Es sind also zwei Zeichen
'1' ist ein Zeichen, das die Ziffer für Eins darstellt. IM ASCII ist das der Wert 49
'\1' ist ein Zeichen, das den Wert 1 hat. Siehe Escapesequencen und ASCII.
1 ist der Wert 1.Die erste Speicherstelle enthält ein 'H'
-
Vielen Dank habe es nun endlich verstanden
-
buu2188 schrieb:
was ist ein
char*
dann? Ich dachte es wäre das selbe wie
char[]
Ich hab' mir wirklich Mühe gegeben. Hast du wenigstens versucht, mein Geschreibsel zu verstehen!???
-
Ja vielen Dank auch dafür nur war mich das nicht so ganz plausibel
-
buu2188 schrieb:
[...]das nicht so ganz plausibel
Ernsthaft, lies ein gutes Buch. Mir hat das sooo viel geholfen. Lies die Bücher von Scotti, dann eins von Struppi, dann bist du auf nem - ich sag mal - gutem Stand.
Ernsthaft.
-
Eine andere Frage bin nun in diesem Kapitel meines Skriptes ...
Für was macht man Zeiger auf eine Klasse bei der Erzeugung eines Objektes für die dynamische Speicherverwaltung ? ( Ist mir nicht so ganz plausibel )
Mfg
-
Deine Frage ist so schwammig, das der Versuch einer Antwort unsinnig wäre. Was? Wie? Wo? Beispiel?
-
Für was macht man Zeiger auf eine Klasse bei der Erzeugung eines Objektes für die dynamische Speicherverwaltung ?
Ich verstehe die Frage nicht, kannst du die bitte verständlich formulieren?
Was ist ein "Zeiger auf eine Klasse"? Ein Zeiger zeigt auf Objekte (oder auf nichts).
Und was ist ein Objekte "für die dynamische Speicherverwaltung"? Einen std::allocator meinst du damit nicht, oder?
Ich schließe mich igivuatips Ratschlag an!
-
Kein Problem
Text:
Einzelne Objekte durch dynamische Allokation von Speicher.double* pD= new double; // Syntax eines Basistyps zum Vergleich // Erzeugung einzelner Objekte durch dynamische Allokation von Speicher CWayPoint* pWp1= new CWayPoint; CWayPoint* pWp2= new CWayPoint("Karlsruhe",8.4,40.017); // Verwendung von Objekten, die durch dynamische Allokation erzeugt worden sind pWp1->print(); pWp2->print();
Mein Übeltäter
CWayPoint* pWp1= new CWayPoint;
Was bewirkt das?
-
Sagen wirs so: Solange du keinen trifftigen Grund hast auf den Heap zu allokieren: Allokiere auf den Stack!
-
buu2188 schrieb:
CWayPoint* pWp1= new CWayPoint;
Was bewirkt das?
Initialisiert den Pointer to
CWayPoint
namenspWp1
mit dem Ergebnis einer Allokation von Speicher für ein Objekt des TypsCWayPoint
durchnew
.new
ruft den StandardkonstruktorCWayPoint::CWayPoint()
für das neue Objekt auf.// Warum die Ungarische Notation blöd ist.
//// Ist die eigentliche Frage "Wann dynamisch Speicher anfordern und wann besser nicht?"?