Große Arrays
-
Oder auch mal Boost.Range angucken

-
krümelkacker schrieb:
Es ist nur leider sehr fehleranfällig bzgl Speicherlecks.
Ja, aber nicht, wenn man es richtig macht^^
Hacker schrieb:
Wie das?
Ich komme aus der Java-Region. Wenn man nun c++ lernt, erstellt man erstmal Arrays mit new und lernt dann, dass man diese mit delete[] löschen muss. Später merkt man dann, dass es so eine Klasse vector gibt. Weil ich new und delete länger kenne als vector, sind mir diese vertrauter.
Aber ich gebe zu: mit vector ist es eleganter.
-
Der wichtige Schritt von Java nach C++ ist es aber nicht zu jedem new auch ein delete zu nutzen. Der wichtige Schritt ist es zu lernen, dass man in C++ weitesgehend auf new (und somit auch delete) verzichten kann und im Sinne fehlervermeidender Programmierung auch unbedingt sollte. Stell also bitte sicher, dass du diesen Schritt auch noch gehst. Interessante Stichworte zu diesem Thema sollten Smartpointer und RAII sein.
-
Ramanujan schrieb:
krümelkacker schrieb:
Es ist nur leider sehr fehleranfällig bzgl Speicherlecks.
Ja, aber nicht, wenn man es richtig macht^^
Wenn man es "richtig" macht, verwendet man nicht new/delete in dieser Situation so wie Du es getan hast. Wenn keiner Fehler machen würde, gäb's keine Bugs. Wenn Du den new/delete Code korrekt, also auch ausnahmesicher, haben willst, wird er leider relativ unleserlich:
double* p = new double[999]; try { [...dein kram...] delete[] p; p=0; } catch(...) { delete[] p; throw; }Vergleiche das mit:
vector<double> v (999); [...dein kram...](Tipp: Das erste ist unnötig komplizierter "low-level Dreck". Das zweite ist elegant, leserlich, ebenso effizient und weniger fehleranfällig, da kürzer)
Dein Problem ist, zu glauben, vieles besser zu wissen als erfahrene C++ Programmierer. Du solltest lernen, C++ richtig "zu sprechen" statt Wort-für-Wort Übersetzungen von einer Sprache zu machen, die völlig anders funktioniert.
-
krümelkacker schrieb:
Du solltest lernen, C++ richtig "zu sprechen" statt Wort-für-Wort Übersetzungen von einer Sprache zu machen, die völlig anders funktioniert.

Sehr guter Kommentar.
-
Ich habs jetzt auf die elegante Weise probiert, bekomme aber bei
std::array<double, 2> test;den Fehler
..\src\matrix.cpp:332: error: `array' is not a member of `std' ..\src\matrix.cpp:332: error: expected primary-expression before "double" ..\src\matrix.cpp:332: error: expected `;' before "double"Unterstützt mein Compiler array nicht oder woran liegt das?
Bei
std::vector<std::array<T, dim2_>> datA_(dim1_);habe ich noch mehr Fehler:
..\src\matrix.cpp:333: error: `array' is not a member of `std' ..\src\matrix.cpp:333: error: `array' is not a member of `std' ..\src\matrix.cpp:333: error: `Matrix<T>::dim2_' cannot appear in a constant-expression ..\src\matrix.cpp:333: error: `Matrix<T>::dim1_' cannot appear in a constant-expression ..\src\matrix.cpp:333: error: a function call cannot appear in a constant-expression ..\src\matrix.cpp:366: error: template argument 1 is invalid ..\src\matrix.cpp:366: error: template argument 2 is invalid ..\src\matrix.cpp:366: error: expected unqualified-id before '}' tokenMuss ich dim1_ bzw. dim2_ zu const casten oder wie löse ich das Problem?
-
Du musst den Header
<array>oder, falls das nicht klappt,<tr1/array>einbinden. Außerdem musst du gegebenenfalls mit C++11-Unterstützung kompilieren (bei g++ mit --std=c++0x).
-
Ich glaube mein Compiler unterstützt kein C++11. Gibt es eine elegante Lösung, die ohne array auskommt? Das wäre mir am Liebsten, da es noch 2 andere Rechner gibt, auf denen mein Programm laufen soll. Könnte gut sein, dass die auch Probleme mit haben.
-
Ramanujan schrieb:
Ich glaube mein Compiler unterstützt kein C++11.
Wie wäre es, wenn du noch dazu schreibst welchen Compiler du nutzt?
Im Übrigen hat die (nicht) Unterstützung von std::array nichts mit der Lauffähigkeit des Programms zu tun. Das Kompilat weiß nichts mehr von std::array.
-
Ramanujan schrieb:
..\src\matrix.cpp:332: error: `array' is not a member of `std' ..\src\matrix.cpp:332: error: expected primary-expression before "double" ..\src\matrix.cpp:332: error: expected `;' before "double"..\src\matrix.cpp:333: error: `array' is not a member of `std' ..\src\matrix.cpp:333: error: `array' is not a member of `std' ..\src\matrix.cpp:333: error: `Matrix<T>::dim2_' cannot appear in a constant-expression ..\src\matrix.cpp:333: error: `Matrix<T>::dim1_' cannot appear in a constant-expression ..\src\matrix.cpp:333: error: a function call cannot appear in a constant-expression ..\src\matrix.cpp:366: error: template argument 1 is invalid ..\src\matrix.cpp:366: error: template argument 2 is invalid ..\src\matrix.cpp:366: error: expected unqualified-id before '}' tokenDie Fehlermeldungen sehen mir nach dem GCC aus. Die aktuellen Versionen dieses Compiler unterstützten auch std::array. Dazu ist der entsprechende Header einzubinden. Aber std::array ist hier nicht das, was Du haben willst, sondern std::vector!
Ramanujan schrieb:
Muss ich dim1_ bzw. dim2_ zu const casten oder wie löse ich das Problem?
Die Werte von dim1_ und dim2_ sind bei Dir zur Compile-Zeit unbekannt. Aber das ist eine notwendige Bedingung für eine "constant expression". Da hilft auch kein cast.
Siehe hier.
kk
-
@krümelkacker Hast du den Anfang des Threads gelesen?
-
cooky451 schrieb:
@krümelkacker Hast du den Anfang des Threads gelesen?
Ja. Ich habe Deinem ersten Kommentar auch voll zugestimmt. Den Verweis auf die Matrix-Klasse habe ich gesetzt, weil ich matrix.cpp und auch so Dinger wie Matrix<T>::dim2_ und Matrix<T>::dim1_ in den Fehlermeldungen gesehen habe.

Das sieht mir hier nämlich wie ein Fall von "ich sag euch nicht, was ich machen will, sondern nur wie und wo ich dabei Probleme hatte" aus.
-
Ich benutze hier MinGW 5.1.4
Im Uni-Poolrechner müsste das die gleiche Version sein.
Auf dem Ubuntu-Server läuft gcc 4.4.3Auf letztere hab ich keinen Einfluss. Kann ich per Parameter testen, ob c++11 unterstützt wird?
Wenn ich (wie ipsec sagte) "--std=c++0x" als Parameter angebe, kommt folgende Ausgabe:
g++ -O0 -g3 -Wall -c -fmessage-length=0 --std=c++0x -o src\Useful.o ..\src\Useful.cpp cc1plus.exe: error: unrecognized command line option "-std=c++0x" Build error occurred, build is stoppedEdit:
Auf dem Server macht der Parameter "--std=c++0x" keine Probleme.
-
GCC 4.4 unterstützt C++0x, das ist ab 4.3 in Teilen dabei.
Hast du überhaupt "#include <array>" drin? Dann lass das --std=c++0x weg und poste die Fehlermeldung.
-
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o src\matrix.o ..\src\matrix.cpp
..\src\matrix.cpp:20:17: array: No such file or directorybzw. wenn ich "#include <tr1/array>" schreibe:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o src\matrix.o ..\src\matrix.cpp
..\src\matrix.cpp:20:21: tr1/array: No such file or directory
-
Gib mal in die MinGW Konsole ein:
mingw-get install g++
-
C:\MinGW\bin>mingw-get install g++
install: gcc-c++-4.6.1-2-mingw32-bin.tar.lzma
installing gcc-c++-4.6.1-2-mingw32-bin.tar.lzma
mingw-get: *** ERROR *** package gcc-c++-4.6.1-2-mingw32-bin.tar.lzma is already
installedEdit:
Eine Frage noch zu array:
muss die Größe von array (also der 2. template-parameter) bereits zur Compilezeit feststehen oder kann das auch eine beliebige Variable sein. Wenn es nämlich ersteres ist, ist array für mich ungeeignet.Edit^2:
ich poste hier mal ein kurzes konkretes Stück Code. Vllt könnte mir das jemand mal mit vector (etc.) formulieren:Matrix<T> Matrix<T>::multiplyNaiveUnchecked(const Matrix<T>* matrix) const { // [...] T** datA = new T*[dim1_]; for (int i = 0; i < dim1_; i++) { datA[i] = new T[dim2_]; for (int j = 0; j < dim2_; j++) datA[i][j] = getEntry(i,j); } // [...] for (int i = 0; i < dim1_; i++) delete[] datA[i]; delete[] datA; // [...] }
-
Ramanujan schrieb:
C:\MinGW\bin>mingw-get install g++
install: gcc-c++-4.6.1-2-mingw32-bin.tar.lzma
installing gcc-c++-4.6.1-2-mingw32-bin.tar.lzma
mingw-get: *** ERROR *** package gcc-c++-4.6.1-2-mingw32-bin.tar.lzma is already
installedEine Frage noch zu array:
muss die Größe von array (also der 2. template-parameter) bereits zur Compilezeit feststehen oder kann das auch eine beliebige Variable sein. Wenn es nämlich ersteres ist, ist array für mich ungeeignet.Ja, dann musst du std::vector nehmen.
std::array ist nämlich der Ersatz für ruhe Arrays.Trotzdem finde ich es merkwürdig dass es bei dir nicht klappt, aber keine Ahnung was nicht stimmt.
-
@Ramanujan Mit GCC 4.6.1 sollte -std=c++0x kein Problem sein. Ja, bei std::array muss die Größe eine Compiletime-Konstante sein. (Wie auch bei normalen Arrays, die du ja am Anfang präsentiert hast..)
Für eine Matrixklasse mit dynamischer Größe siehe den Link von krümelkacker.
-
cooky451 schrieb:
@Ramanujan Mit GCC 4.6.1 sollte -std=c++0x kein Problem sein. Ja, bei std::array muss die Größe eine Compiletime-Konstante sein. (Wie auch bei normalen Arrays, die du ja am Anfang präsentiert hast..)
Also ich konnte normale Arrays auch mit variabler Größe erstellen. Am Anfang dieses Threads hab ich was mit konstanten werten präsentiert, da jene Kombination (100000*4) Probleme gemacht hatte.