Segmentation fault
-
Es ist UB, und so obv.
-
314159265358979 schrieb:
und so obv.
Was?
Ich hab übrigens den Stanard-Teil gefunden:
3.7.4.1, Klausel 3:
C++-Standard schrieb:
An allocation function that fails to allocate storage can invoke the currently installed new-handler function, if any. [...(note)] If an allocation
function declared with a non-throwing exception-specification fails to allocate storage, it shall return
a null pointer. Any other allocation function that fails to allocate storage shall indicate failure only by
throwing an exception of a type that would match a handler (15.3) of type std::bad_alloc (18.6.2.1).Klausel 2 von 3.7.4 sagt, diese Funktionen sind die globalen:
void* operator new(std::size_t); void* operator new[](std::size_t);//Keine exception-specification void operator delete(void*); void operator delete[](void*);Also ist das kein UB.
-
Hacker schrieb:
Ich hab übrigens den Stanard-Teil gefunden:
Nee, das ist nicth der richtige Standard-Teil:
Ich schreib mal was dein Code macht:
long double *ptr; // = 0xirgendwas try { ptr = new long double[1000 * 1000 * 1000]; //heißt: //1) rufe operator new auf (wirft exception) //2) weise das Ergebnis ptr zu. HIER KOMMST DU NIE HIN } catch(std::bad_alloc& b) { //ptr hat hier immernoch den Wert 0xirgendwas std::cerr << "Error allocating memory with new!\n" << b.what() << '\n';//Edit: Danke an Tyrroxx delete[] ptr; // also delete 0xirgendwas - AUTSCH return 255; } }Dass es bei dir nicht kracht, ist vielleicht darauf zurückzuführen, dass dein Compiler im Debug-Build Variablen pauschal mit 0 initialisiert - delete NULL ist dann harmlos. Versuchs mal im Release-Build, oder weise ptr bei der Initialisierung explizit irgendeinen Müll zu.
-
314159265358979 schrieb:
Dein delete im catch-Block ist UB du Pflaume.
the behavior is undefined if the value supplied to operator
delete[](void*) in the standard library is not one of the values returned by a previous invocation of
either operator new[](std::size_t) or operator new[](std::size_t, const std::nothrow_t&) in the
standard library.Na gut, hast Recht.

Edit: @pumuckl: Immer noch alles gut... :p
#include <iostream> #include <exception> int main() { long double *ptr(0x16848486); try { ptr = new long double[1000 * 1000 * 1000]; delete [] ptr; } catch(std::bad_alloc& b) { std::cerr << "Error allocating memory with new!\n" << b.what() << '\n'; delete [] ptr; return 255; } }
-
Ich habe den Fehler gefunden:
Es war noch relativ alter Code und damals wusste ich nicht, dass man sowas hier nicht machen sollte:double b[n];Ich hab es jetzt durch
vector<double> b(n)ersetzt.
-
O.O du bist ja auch noch da.
-
Ramanujan schrieb:
Ich habe den Fehler gefunden:
Es war noch relativ alter Code und damals wusste ich nicht, dass man sowas hier nicht machen sollte:double b[n];Ich hab es jetzt durch
vector<double> b(n)ersetzt.
Gute Idee

Das war übrigens nicht nur alt, sondern auch falsch, da, wenn n keine Compilezeitkonstante ist, du da eine spezielle Compilererweiterung benutzt, die, soweit ich weiß, nur der GCC kennt. Der Fehler ist übrigens, dass du vorher das Array auf dem Stack (d.h. dem automatischen Speicher) angelegt hast. Normalerweise hat der eine recht restriktive Obergröße (meistens im einstelligen oder niedrigen zweistelligen Megabytebereich), sofern man nichts dagegen unternimmt (aber da sollte man gute Gründe für haben). Bei 1400000 double, das sind auf den meisten Systemen gut 10 MB, war dann einfach Schluss. vector legt die Daten im dynamischen Speicher (dem Heap) ab, da bist du normalerweise nur durch die vorhandene Hardware und/oder die Fähigkeiten des Betriebssystems beschränkt.
P.S.: Da ich die Begriffe etwas unklar benutzt habe eine Erläuterung: Der C++-Standard beschreibt drei (seit C++11 vier) verschiedenen Speicherarten von Variablen: statisch, automatisch und dynamisch. Stack (automatisch), Heap (dynamisch) und Datensegment (statisch) sind eine, aber nicht die einzige, mögliche Umsetzung dieser Konzepte, die von vielen C++-Implementierungen (und so ziemlich allen anderen Compilern für andere Sprachen auch) benutzt wird.
-
SeppJ schrieb:
Normalerweise hat der eine recht restriktive Obergröße (meistens im einstelligen oder niedrigen zweistelligen Megabytebereich)
AFAIR ca. 1 MB.
-
Hacker schrieb:
AFAIR ca. 1 MB.
Ist ganz plattformabhängig. Ich kann mich auf älteren Krücken an Stackoverflows bei 128MB erinnern...
-
Hacker schrieb:
SeppJ schrieb:
Normalerweise hat der eine recht restriktive Obergröße (meistens im einstelligen oder niedrigen zweistelligen Megabytebereich)
AFAIR ca. 1 MB.
[14:42:36][~][0]$ ulimit -a ... stack size (kbytes, -s) 8192 ...
-
Hab mich gerade erinnert, bei VC ist der default-wert für die stack größe 1MB. So hab ichs gelesen.
-
Es müssen (bei dem System, auf dem ich getestet habe) mindestens 9 MB gewesen, sein, sonst hätte n = 1,2M mit double nicht funktioniert.
-
Mal eine Frage am Rande: Wann wirft new denn jetzt eigentlich eine Exception?
Wenn ich dieses Programm bei mir ausführe
#include <iostream> #include <stdexcept> int main() { while(true) { try { int* p = new int; } catch(std::bad_alloc& e) { std::cout << "Exception!\n"; std::cout << e.what(); } } }kann ich wunderbar im Taskmanager verfolgen, wie die Verwendung meines Arbeitsspeichers von ziemlich genau 1GB auf ziemlich genau 3GB in ein paar Sekunden anschwillt, er dann kurz bei 3GB bleibt und mein Programm dann einfach folgendes ausgibt und sich beendet:
"This application has requested the Runtime to terminate it in an unusual way. Please contact [...]."
Dann hab ich sofort wieder nur 1GB in Gebrauch. Nix mit "Exception!".
Bei long double* x = new long double[fette Zahl] krieg ich sofort eine.

-
Das mag daran liegen, dass du im catch-Block wiederum eine Exception erzeugst, nämlich wenn cout versucht, sich ein paar bytes für den buffer zu besorgen, den es für die Ausgabe braucht. Mit einzelnen ints schhsffst du es tatsächlich, wirklich alles was dein OS dir an Speicher zu geben vermag, nach und nach vollzupacken.
Das was dein Taskmanager dir anzeigt ist im Übrigen nur ein ganz grober Wert, das ist das, was das Betriebssystem für deinen Prozess reserviert hat. Mit dem, was der Prozess grade tatsächlich bemötigt/benutzt, muss das nicht viel zu tun haben.
-
Bei mir gibt es auch keine Exception:
[18:20:08][/[i][/i]tmp][0]$ ./test Getötet
EDIT:
Ist jetzt BB-Code deaktiviert oder warum geht das nicht?
-
pyhax schrieb:
Ist jetzt BB-Code deaktiviert oder warum geht das nicht?BB versucht deinen [/tmp] tag mit dem [cpp]-Tag zu matchen und gerät durcheinander
Lösung: [/tmp]-Tag mit einem anderen Tag-auf-zu unterbrechen:[/[i[b][/b]][[b][/b]/i]tmp]