kombination dynamisches und statisches array, möglich?
-
"Hallo Welt"
Ich hab da eine Frage bezüglich der kombination eines dynamischen und statischen arrays, verzeiht mir bitte wenn ich nicht alle Normen einhalte was das schreiben dieses Themas betrifft, ist mein erster Beitrag... Freue mich aber auf belehrungNun zu meinem Problem:
Ich möchte ein dynamisches Array bzw. einen std::vector mit einem statischen verbinden... so der code:std::vector<double>* p_array; p_array = new std::vector<double>[5];
Bis dato bekomme ich auch noch keine Fehlermeldung, aber beim versuch in das 0te array auf den vector zu greifen scheitere ich:
p_array[0]->push_back(0.001); (*p_array[0])[0]=0.002;
Hier bekomme ich den Fehler:
[BCC32 Fehler] Unit1.cpp(22): E2288 Zeiger auf Struktur auf linker Seite von -> oder von ->* erforderlich*
Der ist mir ja auch bestens bekannt aber ich wollte ja nicht mit dem []operator auf den vector zugreifen sondern lediglich den zeiger manipulieren, sodass ich beim(in diesem fall 0 ten) vector ankomme.
ich weiß dass man auf einen dynamisch, mit new erstellten, vector mit dem []operator nur dann zugreifen kann wenn man das objekt verwendet...
std::vector<double>* p_array2; p_array2 = new std::vector<double>; p_array2->push_back(0.001); (*p_array2)[0]=0.002;
aber dass will ich ja garnicht...
kann man statische und dynamische arrays überhaupt kombinieren?oder muss ich dann voll dynamisch arbeiten:
std::vector< std::vector<double>* >* p_array;
-
p_array[0].push_back(0.001);
Der []-Operator dereferenziert dir das ja bereits und dann kannst du mit dem .-Operator auf das Element zugreifen.
Also gehen tut es, aber ich sehe den Sinn nicht ganz dahinter, da es ja nicht wirklich statisch ist. new wird ja gebraucht um das ganze dynamisch zu gestalten, da ein einfaches Array ja zur Laufzeit bekannt sein muss. (Also die Grösse).
In deinem Fall ist wohl einstd::vector<std::vector<double> >
am angebrachtesten. Ansonsten, wenn die Dimension sicher konstant ist, kannst du ein normales Array benutzen, oder Boost::Array, welches einen Wrapper für ein Array darstellt. (Ist auch in TR1 enthalten).btw:
Du hast für einen Anfänger einen sehr vorbildlichen Beitrag geschrieben.
Du hast die Tags benutzt, die Fehlermeldung gebracht.
Das einzige, was mich ein wenig verwirrt hat, war, dass du glaube ich 2 mal das gleiche beschrieben hast, kann das sein?
-
chaos104 schrieb:
verzeiht mir bitte wenn ich nicht alle Normen einhalte was das schreiben dieses Themas betrifft, ist mein erster Beitrag... Freue mich aber auf belehrung
Im Vergleich zu einigen anderen (beispielsweise der "Bitte hilfe!!!"-Thread) machst du das aber sehr gut. Sogar die CPP-Tags verwendest du richtig, das machen die Wenigsten auf Anhieb.
Ach, jetzt hat grad drakon geschrieben, was ich wollte... :p
Naja, ein verschachtelter Vector oder einstd::tr1::array<std::vector<double>, 5>
(der von drakon erwähnte Array-Wrapper) würde ich auch empfehlen.
-
Zum Sinn des ganzen, ich bin über das ganze gestolpert als ich ein Vokabeltrainer geschrieben habe, und konnte mir nicht erklären wieso es nicht funktioniert, klar hätte ich mit einem workaround weitermachen können aber es ging darum das ganze zu verstehen...
Das Programm sollte, auch wenn es schon 1000 bessere programme für sowas gibt, die heimische Vokablebox abbilden, also 5 fächer mit beliebig vielen Vokabelkarten...
Es ging mir aber eigentlich nicht darum auf ein objekt im vector zuzugreifen sondern ein statisches also 5 stelliges array mit vectoren zu einzurichten.
Und da statische arrays sowieso zeiger sind dachte ich ich kann das ganze auch gleich mit new ins leben rufen...Im Programm sah das ganze so aus:
CVoc ist hierbei die Klasse die eine Vokabelkarte darstellt...[cpp]
class CVocTrainer
{
private:
std::vector< CVoc* > * mp_Voc;
...
public:
CVocTrainer()
{
mp_Voc = new std::vector< CVoc * > [5];
...
}
};[/cpp]
-
Was genau hab ich jetzt mit den C++ tags falsch gemacht?
Ich hab sie genau so verwendet wie im Beitrag zuvor...
-
chaos104 schrieb:
Und da statische arrays sowieso zeiger sind...
Nein, statische Arrays sind keine Zeiger. Dass man sie oft wie Zeiger behandeln kann, liegt daran, dass sie implizit in Zeiger konvertierbar sind. Prüf doch mal, was
sizeof
dazu sagt...chaos104 schrieb:
... dachte ich ich kann das ganze auch gleich mit new ins leben rufen...
Und damit du wieder eine Stelle mehr im Programm hast, wo du an die Freigabe denken musst. Deshalb wenn möglich Container verwenden.
chaos104 schrieb:
std::vector< CVoc* > * mp_Voc;
Wieso einen Zeiger auf einen
vector
, der aus Zeigern aufCVoc
besteht? Wenn du den inneren Zeiger nicht für einen bestimmten Grund (z.B. Polymorphie) brauchst, kannst du ihn weglassen. Oder sogar beide:std::vector<CVoc> mp_Voc;
Dann brauchst du dich nämlich nicht mehr um die Speicherverwaltung zu kümmern.
Ein statisches Array mit
std::vector
sähe z.B. so aus:std::vector<CVoc> mp_Voc[5];
Aber wie gesagt nimmst du besser Container.
chaos104 schrieb:
Was genau hab ich jetzt mit den C++ tags falsch gemacht?
Ich hab sie genau so verwendet wie im Beitrag zuvor...Du darfst innerhalb des Codes keine weiteren Tags (z.B. [b]) verwenden.
-
chaos104 schrieb:
Was genau hab ich jetzt mit den C++ tags falsch gemacht?
Ich hab sie genau so verwendet wie im Beitrag zuvor...Formattierungen im Code sind böse.
(die fetten Punkte)
Du kannst ansonsten ja so ein Array machen::
std::vector<double> v[5];
Dann hast du 5 vectoren mit beliebig vielen double's. Ist es das, was du willst?
Und da statische arrays sowieso zeiger sind dachte ich ich kann das ganze auch gleich mit new ins leben rufen...
Das stimmt nicht ganz. Arrays lassen sich implizit in Zeiger casten, spielt bei deinem Beispiel nicht so eine Rolle. Nur das du dir es im Hinterkopf behälst.;)
-
Erst mal zu meinem Problem mit den C++ Tags, danke ich wusste nicht dass ich danichts mehr mit anderen tags machen darf ich wollte mit den punkten nur darstellen das ich nicht die ganze Klasse abgebildet habe...
Ich benutze Zeiger in den vector um die Vokablen von einer Box in die andere zu verschieben... Wenn ich das mit objekten machen würde müsste ich das ganze ja jedes mal kopieren und nicht nur die Zeiger verschieben...
Aber Danke für alle Antworten
-
Und was spricht dagegen, Zeiger auf deine Objekte in den vector zu schmeißen?
-
chaos104 schrieb:
Vielleicht nochmals zum Unterschied: Statische Arrays werden auf dem "Stack" (statischer Speicherbereich) angelegt, da wird einfach der Stackzeiger verschoben. Dynamische Arrays (
new
in C++,malloc()
in C) werden auf dem "Heap" (dynamischer Speicherbereich) allokiert, es wird also zur Laufzeit ein freier Speicherbereich gesucht, reserviert und der Zeiger darauf zurückgegeben. (Die Bezeichnungen sind nicht ganz korrekt, aber werden umgangssprachlich häufig so benutzt).Wenn du jetzt Folgendes schreibst:
int StaticArray[5];
Dann ist
StaticArray
ein statisches Array mit 5 Elementen und kein Zeiger - der Typ istint[5]
.int* DynamicArray = new int[5];
Hier hingegen ist
DynamicArray
ein Zeiger, der auf einen zusammenhängenden Speicherbereich auf dem "Heap" zeigt. Der Typ istint*
.Wenn du
Array[x]
schreibst, läuft das bei beiden auf das selbe hinaus. Das statische Array wird implizit in einen Zeiger konvertiert, und dann wird Zeigerarithmetik angewandt:Array[x] == *(Array + x);
Beim dynamischen Array wird halt direkt zum Zeiger ein Offset (wie du sagst
sizeof(Typ)*x
) addiert.
-
Ah,ok. Ich verstehe, was du willst. Wäre es dann aber nicht angebrachter alle Vokablen zu laden an einem zentralen Ort und dann die zu verteilen? - Fände ich besser gelöst, als da etwas mit (unnötigen und "gefährlichen") Operationen zu basteln.
Arrays sind ein eigenes Konzept. Es wird oft von Autoren als Zeiger auf den Anfang des Speichers dargestellt, was aber nicht so einfach dargestellt werden darf. Arrays lassen sich zu einem Zeiger, der das macht implizit umwandeln. Selbst ist der Name aber einfach ein Array. (Probier sonst mal ein Array zu inkrementieren und dann versuch das mal mit einem Zeiger, dann siehst du, dass es verschiedene Konzepte sind.)