Vorzeichenlose Ganzzahlen in C ++ für Schleifen

8

Ich habe etwas über Stackoverflow über Reverse für Schleifen in C ++ geforscht, die eine Ganzzahl ohne Vorzeichen und keine mit Vorzeichen verwenden. Aber ich verstehe immer noch nicht, warum es ein Problem gibt (siehe Unsigned int umgekehrte Iteration mit for-Schleifen ). Warum führt der folgende Code zu einem Segmentierungsfehler?

%Vor%

Ich verstehe, dass das Problem ist, wenn der Index i gleich Null ist, weil es so etwas wie einen Überlauf gibt. Aber ich denke, eine vorzeichenlose ganze Zahl darf den Nullwert annehmen, oder? Jetzt, wenn ich es durch eine vorzeichenbehaftete Ganzzahl ersetze, gibt es absolut kein Problem.

Kann mir jemand den Mechanismus hinter dieser Reverse-Schleife mit einer vorzeichenlosen Ganzzahl erklären?

Vielen Dank!

    
Benjamin 28.01.2012, 08:54
quelle

4 Antworten

24

Das Problem hier ist, dass eine vorzeichenlose Ganzzahl niemals negativ ist.

Daher der Schleifentest:

%Vor%

wird immer wahr sein. So erhalten Sie eine Endlosschleife.

Wenn es unter Null fällt, wird es auf den größten Wert unsigned -Wert umgebrochen.
Damit greifen Sie auch auf x[i] out-of-bounds zu.

Dies ist kein Problem für vorzeichenbehaftete Ganzzahlen, da es einfach negativ wird und somit i >= 0 ausfällt.

Wenn Sie also Ganzzahlen ohne Vorzeichen verwenden möchten, können Sie eine der folgenden Möglichkeiten ausprobieren:

%Vor%

und

%Vor%

Diese beiden wurden von GManNickG und AndreyT aus den Kommentaren vorgeschlagen.

Und hier sind meine ursprünglichen 3 Versionen:

%Vor%

oder

%Vor%

oder

%Vor%     
Mysticial 28.01.2012, 08:57
quelle
6

Das Problem ist, dass Ihre Schleife es zulässt, dass ich so niedrig wie Null bin und nur erwarte, die Schleife zu verlassen, wenn i kleiner als 0 ist. Da i nicht signiert ist, kann sie niemals kleiner als 0 sein 32-1. Das ist größer als die Größe Ihres Vektors und führt zu einem segfault.

    
MAK 28.01.2012 08:58
quelle
4

Was auch immer der Wert von unsigned int i ist, es ist immer wahr, dass i >= 0 , so dass Ihre for Schleife niemals endet.

Mit anderen Worten, wenn i zu einem bestimmten Zeitpunkt 0 ist und Sie es dekrementieren, bleibt es immernegativ, weil es dann eine riesige Zahl enthält, wahrscheinlich 4294967295 (das sind 2 32 ) -1).

    
Basile Starynkevitch 28.01.2012 08:58
quelle
3

Das Problem ist hier:

%Vor%

Sie beginnen mit einem Wert von 9 für ein unsigned int und Ihre Exit-Definition ist i & gt; = 0 und dies wird immer wahr sein. (unsigned int wird niemals negativ sein !!!). Aus diesem Grund wird Ihre Schleife von vorne beginnen (Endlosschleife, weil i = 0, dann -1 maximal).

    
Beachwalker 28.01.2012 09:02
quelle

Tags und Links