Maximale Größe von std::vector
-
@ Dravere
Soviel ich weiss, istsize_typebei Containern ein Typedef aufsize_typedes benutzten Allokators (hab ich zumindest hier gehört). Beim Standardallocator sollte es mitstd::size_tübereinstimmen.@ The Kenny
Schön, dass du die Erkenntnisse dieses Threads nochmals zusammenfasst. :p
-
Nexus schrieb:
@ Dravere
Soviel ich weiss, istsize_typebei Containern ein Typedef aufsize_typedes benutzten Allokators (hab ich zumindest hier gehört). Beim Standardallocator sollte es mitstd::size_tübereinstimmen.So leid es mir tut, aber da irrt sich Shade of Mine einmal. Es stimmt zwar, dass beim default allocator
size_typeeintypedefaufsize_tist, aber es ist nicht im Standard definiert, dass dersize_typeeinesvectors auch eintypedefauf densize_typedesallocators ist.In "23.2.4 Template class vector" Abschnitt 2 steht das folgende:
// ... typedef /*implementation defined*/ size_type; // See 23.1 typedef /*implementation defined*/ difference_type; // See 23.1 // ...Und in "23.1 Table 65 - Container Requirements" steht, dass
size_typeeinunsigned integral typesein soll, welcher jegliche positive Darstellung vondifference_typeaufnehmen kann.
Unddifference_typeist einsigned integral type, welcher die Differenz von zwei Iteratoren aufnehmen können muss.Mehr gibt es dazu nicht im C++ Standard 98.
Aber nebst diesem Körnerpicken, muss man natürlich schon sagen, dass die meisten Implementation es so handhaben, wie Shade Of Mine es sagt. Es steht halt einfach nicht im Standard, dass es so sein muss.
Grüssli
-
Okay, danke. Aber welchen Sinn hat dann das
size_typedes Allokators, wenn der Container nicht darauf abgestimmt sein muss? Damit geht ja jede Aussagekraft verloren...
-
Nexus schrieb:
Okay, danke. Aber welchen Sinn hat dann das
size_typedes Allokators, wenn der Container nicht darauf abgestimmt sein muss? Damit geht ja jede Aussagekraft verloren...Das stimmt nicht ganz.
size_typeist indirekt an den Allokator gebunden überdifference_type, bzw. der Abstand von den Iteratoren. Wieso man die Bindung nicht stärker gemacht hat, weiss ich auch nicht. Mir leuchten sowieso einige Dinge im Standard nicht ganz ein (wie zum Beispiel signed -> unsigned standardisiert, unsigned -> signed nicht ganz standardisiert
).Vielleicht weiss jemand anderes mehr dazu...
Grüssli
-
Bulli schrieb:
Der Vector kann soviel Elemente verwalten, wie size_t auf deinem Compiler groß ist.
std::cout << sizeof(std::size_t);4

-
hm... ich kann bei dem Problem leider nicht helfen, aber ich habe noch eine andere Frage dazu:
Ist es nicht unüblich "std::cout" schreiben? Ist es nicht üblicher, wenn man am Anfang vor "int main()" schreibt "using namespace std;" Dann muss man nicht mehr "std::cout" schreiben, sondern einfach nur "cout"? Liege ich da richtig? Ich bin erst seit ca. 1 Monat in der C++ Welt und kenne mich daher noch relativ wenig aus...mfg
-
prochecker schrieb:
Ist es nicht unüblich "std::cout" schreiben?
nein.
Ist es nicht üblicher, wenn man am Anfang vor "int main()" schreibt "using namespace std;" Dann muss man nicht mehr "std::cout" schreiben, sondern einfach nur "cout"? Liege ich da richtig?
genauer: man muss es in alle übersetzungseinheiten schreiben, in denen man auf std::verzichten will. ein nichttriviales programm besteht üblicherweise aus mehr als nur main().
ist letzlich eine geschmacksfrage. ich verzichte in der regel auf using namespace, weil das mehrtippen nicht ins gewicht fällt, bzw. der gewinn an klarheit imho wesentlich mehr wiegt.
-
ein nichttriviales programm besteht üblicherweise aus mehr als nur main().
Bei meinen kleinen Taschenrechnerprogrammen schon

Also ich verwende lieber using namespace std; weiß auch nicht warum
Viel mehr Tipparbeit finde ich es nicht, aber es ist übersichtlicher für mich,...mfg
-
prochecker schrieb:
hm... ich kann bei dem Problem leider nicht helfen, aber ich habe noch eine andere Frage dazu:
Ist es nicht unüblich "std::cout" schreiben? Ist es nicht üblicher, wenn man am Anfang vor "int main()" schreibt "using namespace std;" Dann muss man nicht mehr "std::cout" schreiben, sondern einfach nur "cout"? Liege ich da richtig? Ich bin erst seit ca. 1 Monat in der C++ Welt und kenne mich daher noch relativ wenig aus...Man benutzt das eine dann wenn es sinnvoll ist. Genauso bei dem anderen.
std::XYZ schreibe ich z.B. immer, wenn ich es selten brauche. Wenn ich aber sehr viel Sachen aus dem std-Namespace benutze, schreibe ich using namespace. Mna muß halt abwegen.Manchmal muß man aber std::XYZ explizit benutzen, weil XYZ schon woanders existiert. Und genau dafür sind Namespaces da: um Namenskonflickte zu vermeiden!
-
prochecker schrieb:
Also ich verwende lieber using namespace std; weiß auch nicht warum
Viel mehr Tipparbeit finde ich es nicht, aber es ist übersichtlicher für mich,...Bis du dann sowas hast:
#include <algorithm> using namespace std; int max(int lhs, int rhs) { return lhs > rhs ? lhs : rhs; } int main() { cout << max(4, 223) << endl; return 0; }Ups, der Kompiler weiss nicht welches
max.
using namespacehebelt den Sinn von Namensräumen aus. Man sollte es meiner Meinung nach nur mit Bedacht einsetzen, möglichst in Scopes und auf GAR KEINEN FALL in Headern. Für lange Namen, bzw. stark verschachtelte Namensräume, gibt es ja noch die Zuweisung:namespace ba = boost::asio; // Verwende ba, als würdest du boost::asio schreiben.Allerdings auch hier würde ich die gleichen Regeln wie bei
using namespacehinsetzen.In Scope bedeutet übrigens sowas:
void foo() { using namespace std; // ... } // using namespace std, gilt nur bis hier.Edit: Das nächste Mal bitte einen eigenen Thread eröffnen

Grüssli
-
Also ich setze unsing nur da ein, wo es für die Lesbarkeite des Programmes wirkklich nötig ist. Da kann es enorm viel helfen,wen man nicht dauernd so etwas hat:
myEngine::myMathLib::myVector v; v += myEngine::myMathLib::myVector (4,1,3) - myEngine::myMathLib::myVector(myEngine::myMathLib::myInteger(3),2,1);Da hat man die ganze Zeile voll Zeugs, die nicht von Interesse sind und den eigentlichen Code kann man kaum sehen. Hier kann man gut using einsetzen, da es sehr unwahrscheinlich ist, dass man am genau gleichen Ort unterschiedliche Typen braucht, die gleich heissen.
-
ist es denn nun tatsächlich so, dass ein std::vector auf meinen compiler nur 4 elemente speichern kann, wenn size_t eine größe von 4 hat?
-
holy shit! schrieb:
ist es denn nun tatsächlich so, dass ein std::vector auf meinen compiler nur 4 elemente speichern kann, wenn size_t eine größe von 4 hat?
Soll man auf sowas wirklich antworten? Naja, falls ein Noob über den Thread stolpert ...
Er meinte:#include <limits> #include <iostream> #include <cstddef> int main() { std::cout << std::numeric_limits<std::size_t>::max() << std::endl; return 0; }Aber wie ich schon weiter vorne gepostet habe, hat
std::size_tnix mit der maximalen Grösse desstd::vectoram Hut.Grüssli
-
Dravere schrieb:
Bis du dann sowas hast:
#include <algorithm> using namespace std; int max(int lhs, int rhs) { return lhs > rhs ? lhs : rhs; } int main() { cout << max(4, 223) << endl; return 0; }Ups, der Kompiler weiss nicht welches
max.
using namespacehebelt den Sinn von Namensräumen aus.Hä? using namespace deswegen zu verteufeln ist ja wohl etwas weit hergeholt. Dann macht man halt das:
#include <algorithm> using namespace std; int max(int lhs, int rhs) { return lhs > rhs ? lhs : rhs; } int main() { cout << ::max(4, 223) << endl; // Globaler Scope! Und schon weiß der Compiler was genutzt werden soll return 0; }Im übrigen würde man aber max eh nicht im globalen Scope anlegen. Du hast doch selber eine Regel gebrochen, obwohl du auf eine andere plädierst. Mein max würde ich auch in meinem namespace anlegen, anstatt using namespace zu verteufeln.
-
Dravere schrieb:
Soll man auf sowas wirklich antworten?
Bulli schrieb:
Der Vector kann soviel Elemente verwalten, wie size_t auf deinem Compiler groß ist.
soll man sowas wirklich einfach stehen lassen?
-
@Bulli,
Es ging doch nur darum aufzuzeigen, dass ein Namenskonflikt passieren kann. Ich wollte kein vollwertiges riesiges Konstrukt bauen, wo dann per Zufall ein Namenskonflikt entsteht. Es ist doch nur ein BEISPIEL.Zudem verteufle ich es nicht. Ich rate nur zur Vorsicht. Herje.
@"nö du",
Da die Aussage sowieso falsch ist, ist es egal.Grüssli
-
Wow. Das war aber ganz schön Off Topic.
Auf jeden Fall Danke an alle die was beigetragen haben.
Jetzt läuft das Programm. Ich war kurz davor std::deque zu verwenden,
da hab ich mir gedacht versuchs doch mal so:
Da ich ja am Anfang nicht weis wie groß der Vector wird habe ich ihn
immer für jeden Eintrag mir resize erweitert. Jetzt hab ich erst die
Zeilen in der Datei gezählt, die vectoren einmal angelegt und siehe da: Es geht!
Kostet mich aber 30 sec. mehr Laufzeit. Aber bei 2-5 Stunden läßt sich das verschmerzen
-
Ja, das ist eine sehr gute Lösung! Denn so wird der Speicher nicht unnötig fragmentiert, was ja vorher wohl tatsächlich mächtig freien Speicher verschwendete.
-
Da ich ja am Anfang nicht weis wie groß der Vector wird habe ich ihn
immer für jeden Eintrag mir resize erweitert.Aber dir ist klar, dass das unnötig war?!
Jetzt hab ich erst die Zeilen in der Datei gezählt, die vectoren einmal angelegt und siehe da: Es geht! Kostet mich aber 30 sec. mehr Laufzeit. Aber bei 2-5 Stunden läßt sich das verschmerzen
Das halt ich für nen Gerücht, dass es jz länger braucht, obwohl es nicht mehr aller x Einträge umkopieren muss...
btw: Im Release-Mode compiliert?bb
-
es dauert definitiev länger.
Ich mess die Zeit mit:
time(&start);
...vectoren anlegen, datei einlesen...
time(&stop);
cout << stop-start << endl;
(was ich der einfachheit halber unterschlagen hab: in der datei
stehen die zeilen nicht einfach so sondern in sektionen unterteilt.
am anfang jeder sektion steht wie viele zeilen jetzt kommen.
Typischerweise einige tausend... also wird der wevtor nicht bei
jeder zeile vergrößert sondern immer in tausenderschritten)macht ne differenzevon 30 sec.
ansonsten verwende ich den intel C++ Compiler 11 mit den Parametern:
icpc -openmp -parallel -fast main.cppBin aber noch nicht so der Compilerexperte. Wenn jemand optionen kennt die die
Performance verbessern könnten... Her damit!