Warum wirft Exception andere Exception?

Onkel Schuppig

Erfahrenes Mitglied
Hallo zusammen,
der unten gezeigte Code-Schnipsel reagiert merkwürdig. Ich möchte möglichst am Stück Speicher reservieren. Wenn das nicht möglich ist, dann die Hälfte.
Wenn das auch nicht möglich ist, dann ein Viertel, usw. Beim Test mit zu großem n springt die Routine auch wie beabsichtigt in den catch-Block. Aber danach geht es nicht etwa im try-Block weiter, sondern es wird eine weitere Ausnahme geworfen namens "privileged instruction". Was stimmt denn da nicht?
Info: facemap ist eine std::map und freefaces ein std::vector.

Code:
FaceMap::size_type n(facemap.size());
while (true) {  
   try {
     freefaces.reserve(n);
     break;
   } catch (bad_alloc) {
     n /= 2;
   }
 }
 
Hi.

Die std::vector resize() Methode deiner verwendeten STL Implementierung scheint nicht exception-safe zu sein.

Versuch's mal so:
C++:
FaceMap::size_type n(facemap.size());
while (true) {  
   try {
     std::vector v(n);
     freefaces.swap(v);
     break;
   } catch (bad_alloc) {
     n /= 2;
   }
 }
Welchen Compiler verwendest du denn? Ist das Verhalten mit einem Minimalbeispiel nachvollziehbar?

Gruß

PS: Du solltest übrigens grundlegend Ausnahmen immer by-reference fangen, nicht unbedingt by-value.
 
Zuletzt bearbeitet:
Mein Rechner geht z.B. bei folgenden Beispiel in die Knie. Ich habe 2 GB RAM, Win XP 32, Visual C++ 2005 Prof.
Code:
struct test {
  double v[1000];  // Hauptsache verschwenderisch
};
vector<test> vec;

size_t n = 1000000;
while (true) {  
  try {
    vec.reserve(n);
    break;
  } catch (const bad_alloc&) {
    n /= 2;
  }
}
 
Hmm, wenn ich catch(...) verwende, scheint es zu klappen.
C++:
struct test {
  double v[1000];  // Hauptsache verschwenderisch
};
vector<test> vec;

size_t n = 1000000;
while (true) {  
  try {
    vec.reserve(n);
    break;
  } catch (...) {
    n /= 2;
  }
}
 
Zuletzt bearbeitet von einem Moderator:
Hi.

Das liegt aber dann nicht an einer "privileged instruction" Ausnahme, sondern einfach daran, das du versucht hast mehr als die maximale Anzahl von Elementen des Vektors zu reservieren (std::length_error).

C++:
vec.reserve(std::min(n, vec.max_size()));
Gruß
 
C++:
#include <vector>
using namespace std;

struct test {
  double v[1000];  // Hauptsache verschwenderisch
};
vector<test> vec;

size_t n = 1000000;
while ( true )  {
  try {
    vec.reserve( min( n, vec.max_size() ) );
    break;
  } catch ( const bad_alloc& )  {
    n /= 2;
  }
}
Mit dieser Variante bin ich nun zufrieden.
length_error() kann gar nicht erst auftreten und andere Ausnahmen als bad_alloc werden nicht behandelt. Schließlich sind nicht alle erdenklichen Ausnahmen durch n /= 2 zu lösen.
Vielen Dank!
 
Zuletzt bearbeitet von einem Moderator:
Zurück