[Anfängerfrage] Speicherallokation mit "new" Opertaor
-
Danke für die Antwort,
noch ganz hab ich es nicht verstanden.
Vorweg: Ich korrigiere den Code, indem ich die Zeiger mit delete[] freigebe.
Frage 3:
- pt1 weiß nicht, für wieviel Speicher er alloziiert wurde.
- pt2 weiß, dass er für 3 x sizeof(float) Speicher alloziiert hat.Warum funktioniert die Zuweisung und das Auslesen sowohl für pt1 als auch für pt2? Ich wundere mich deshalb, weil pt1 gar kein und pt2 zu wenig Speicher alloziiert haben, und es für beide dennoch klappt, den Inhalt auszulesen...
Danke
-
Die Zeiger selbst sind vom Typ
float*und zeigen damit auf genau einenfloat-Wert. Bei den Arrays macht man jetzt einen Trick:newreserviert ein Array aus 3floats(= Speicherbereich der Größe3*sizeof(float)) und gibt einen Zeiger auf das erste Element zurück. Der Zeiger zeigt auf genau einen Wert und hat keine Ahnung von dem Array, aber du weißt, dass dahinter noch 2 andere sind und kannst überzeiger+1bzw.zeiger+2darauf zugreifen.
Bei der Zuweisung von dem test-Array an den Zeiger gibt es nun eine Besonderheit, den sog. Array-to-Pointer-Decay. Dabei wird das Array implizit umgewandelt in einen Zeiger auf sein erstes Element. Und dieser wird deinem Zeiger zugewiesen. Dein Zeiegr weiß also immer noch nichts von irgendwelchen Arrays, er zeigt jetzt nur auf ein neuesfloat, bei dem du wiederum weißt, dass dahinter noch 3 weiterefloats liegen. Das alte Array ist für dich verloren, weil du keinen Verweis mehr darauf hast.Die ganze Problematik enthält viele Fallstricke, so dass ich dir rate, rohe Arrays und rohes
newunddeleteam besten gar nicht zu verwenden, sondern auf Klassen der Standardbibliothek (hier z.B.vector) zurückzugreifen.
-
Danke,
jetzt habe ich es verstanden (hoffentlich).
Das heißt also, die Allokation eines Zeiger mittels...= new Typ [MAX]ist nur dann von Bedeutung, wenn ich in diese Speicherzellen schreiben möchte! Und dabei sollte der Zeiger nicht mehr alsMAX-mal inkrementiert werden.Ja, habe mich mit STL: Vector etwas beschäftigt. Sehr handlich. Was mich daran stört, ist, dass ich nicht "einfach" beliebige mathematische Funktionenen auf die Vektorelemente ausführen kann, ohne dabei "transform" und "unitäre Funktionen" schreiben zu müssen.
http://www.cplusplus.com/reference/algorithm/transform/
http://www.cplusplus.com/reference/std/functional/bind1st/Ein weiterer Grund ist, dass ich in einem Framework arbeiten, wo Ein- und Ausgabe mit Pointern geschieht.
Gut, ich weiß zwar wie ich aus einem Vektor ein Array erhalte:std::vector<int> myVec; // <-- Fülle den Vektor int *p_myVec = &myVec[0]; // <-- Führe mathematische Operationen auf die Elemente des Pointers in einer for-Schleife durchAber sind die Elemente im Vektor nun korrekt und sicher modifiziert worden?
Oder fehlt mir hier eine entscheidende Information?
-
ZehMinusMinus schrieb:
Was mich daran stört, ist, dass ich nicht "einfach" beliebige mathematische Funktionenen auf die Vektorelemente ausführen kann, ohne dabei "transform" und "unitäre Funktionen" schreiben zu müssen.
Dann nimm doch einfach std::valarray

-
Kann ich ein Array einfach in ein valarray konvertieren? Wenn ja, ähnlich wie in meinem vorhergehenden Posting?

-
ZehMinusMinus schrieb:
float test[] = {1,2,3,4}; float *pt1 = new float; float *pt2 = new float[3]; //Frage_1: Wird hier 3 Mal size_of(float) Bytes Speicher reserviert? pt1 = test; pt2 = test; // Frage_2: Warum kann ich hier ein Array mit 4 Elementen einem Pointer zuweisen, der jedoch nur für 3 Floatwerte Speicher alloziiert hat? // Das Auslesen beider Pointer ist erfolgreich und gibt in beiden Fällen die Elemente "1", "2", "3" und "4" zurück.Hier liegt möglicherweise noch ein Verständnisproblem vor:
float *pt2 = new float[3];Hier haben wir es mit 2 Objekten und einem Wert zu tun:
1. das Zeigerobjekt pt2 - hierfür wird implizit Speicher reserviert (es ist eine automatische Variable).
2. einem Arrayobjekt des Typs float[3] (also ein Array aus 3 floats) - das Objekt hat keinen Namen und der Speicher hierfür wird explizit mittels des new-Ausdrucks auf dem freestore reserviert.
3. einem Zeigerwert, dabei handelt es sich um den (Rückgabe-)wert von new, dieser Wert repräsentiert die Adresse des Arrays (bzw. des ersten Elementes darin) und wird benutzt, um das Objekt pt2 zu initialisieren.
4. Der Wert des float-Arrays bzw. die Werte seiner Elemente bleiben hier unbestimmt.ZehMinusMinus schrieb:
Das heißt also, die Allokation eines Zeiger mittels
...= new Typ [MAX]ist nur dann von Bedeutung, wenn ich in diese Speicherzellen schreiben möchte!Es ist nicht der Zeiger selbst, der per new reserviert wird, sondern ein anderes Objekt; und die Adresse dieses anderen Objektes wird dann dazu benutzt, das Zeigerobjekt mit einem Wert zu initialisieren.
-
Camper, vielen Dank,
ich habe deine Erkärungen nachvollziehen können

Damit kann ich auch meine Frage_2 für inhaltlich unclever bezeichnen, denn in diesen Zeilen
pt1 = test; pt2 = test;wird nicht der Array samt seinen 4 Elementen übergeben, sondern lediglich die Adresse auf das erste Element dieses Arrays.
Das ganze wäre dann äquivalent zupt1 = &test[0]; pt2 = &test[0];.
- Gibt es eine Möglichkeit von einem Vector in ein ValArray zu kommen?
- Gibt es eine Möglichkeit von einem Array in ein ValArray zu kommen?
- Gibt es eine Möglichkeit von einem Array in ein Vektor zu kommen, ohne die Arrayelemente in den Vektor kopieren zu müssen.
Ich denke dabei an den Umkehrweg zu
std::vector<int> myVec; int *p_myVec = &myVec[0];.
Für jede Hilfe bin ich dankbar.
-
Will du "nur" lernen zu programmieren oder musst du ein technisches Problem lösen?
Da gibt es auch ganz gute Bibliotheken wie z.B. http://de.wikipedia.org/wiki/Armadillo_%28C%2B%2B-Bibliothek%29 die einem so manches abnehmen.
-
ZehMinusMinus schrieb:
- Gibt es eine Möglichkeit von einem Vector in ein ValArray zu kommen?
- Gibt es eine Möglichkeit von einem Array in ein ValArray zu kommen?
std::valarray hat einen Construktor, der Pointer und Größe entgegennimmt, dem kannst du das Array direkt und den vector per
&v.front()oder&v[0]übergeben- Gibt es eine Möglichkeit von einem Array in ein Vektor zu kommen, ohne die Arrayelemente in den Vektor kopieren zu müssen.
Nein, der vector will seine Daten schon selber verwalten und nicht darauf angewiesen sein, daß der externe Speicher (dein Ursprungsarray) überlebt.
Aber ich würde sowieso darauf verzichten, die Daten zwischen verschiedenen Formaten herumzuschieben - pack sie gleich in einen vector<> bzw. valarray und lass sie dann dort.
-
Danke für eure Hilfe!
CStoll schrieb:
std::valarray hat einen Construktor, der Pointer und Größe entgegennimmt, dem kannst du das Array direkt und den vector per
&v.front()oder&v[0]übergebenD.h., hier legt der Konstruktur Kopien im ValArray an? Also Kopien von jenen Elementen, die durch den Pointer adressiert werden.
CStoll schrieb:
]Aber ich würde sowieso darauf verzichten, die Daten zwischen verschiedenen Formaten herumzuschieben - pack sie gleich in einen vector<> bzw. valarray und lass sie dann dort.
Wäre mir auch am liebsten, aber ich arbeite mit der Intel-Bibliothek, und die schluckt für einige Funktionen nur Pointer. Für meine eigenen Berechnung bleibe ich ja bei Vektoren.
Grüße

-
Bei valarray bin ich mir nicht so sicher, aber imho spricht nichts dagegen, der Library einen Zeiger IN deinen vector<> zu übergeben (solange sie keine Dummheiten mit den Zeigern macht oder darauf besteht, den Speicher selber anzufordern, sollte es da keine Schwierigkeiten geben)
vector<double> v1,v2,erg; ... erg.resize(len); lib::add(&v1[0],&v2[0],&erg[0],len);