2009-05-07 9 views
0

Ich habe eine lange nicht signiert, die ich verwende, um die Lautstärke zu verfolgen. Der Datenträger wird um einen weiteren unsigned long long erhöht. Alle 5 Sekunden drucke ich diesen Wert aus und wenn der Wert das vorzeichenlose Maximum von 32 Bit erreicht, gibt der printf mir einen negativen Wert. Das Code-Snippet folgt:Integer Overflow

unsigned long long vol, vold; 
char    voltemp[10]; 

vold = 0; 

später ...

while (TRUE) { 
    vol = atoi(voltemp); 
    vold += vol;  
    fprintf(fd2, "volume = %llu); 
} 

Was mache ich falsch? Dies läuft unter RedHat 4 2.6.9-78.0.5.ELsmp gcc Version 3.4.5

+1

Die fprintf-Zeile fehlt ein dritter Parameter, aber Sie haben das wahrscheinlich falsch [email protected] Bitte füge das nicht einfach hinzu. Es könnte das Problem sein, nach dem wir suchen. @JPM Ist der aktuelle Code der, den du bekommen hast? Können Sie das Problem reproduzieren, wenn Sie vol = 1 setzen? anstatt Atoi zu benutzen? – phihag

+1

Da er sagt, dass es eine negative Zahl druckt, vermute ich, dass es das printf sein muss, das falsch ist. Wenn es nicht falsch wäre, würde% llu eine positive Zahl (was auch immer das ist ein anderes Anliegen) und keine negative Zahl. –

+0

Nun, der printf kann falsch sein (im Gegensatz zu miscopied), aber auch atoi. –

Antwort

0

Nun, ich kann nicht wirklich sagen, weil der Code Syntaxfehler hat, aber hier ist eine Vermutung:

vol = atoi(voltemp); 

atoi konvertiert ascii in Ganzzahl. Vielleicht möchten Sie versuchen atol, aber das bringt es nur zu einem langen, nicht lange.

Ihre C-Standardbibliothek könnte atoll haben.

0

Sie können atoi nicht verwenden, wenn die Zahl die Grenzen von signed int überschreiten kann.

EDIT: atoll (was offensichtlich Standard ist), wie vorgeschlagen, ist eine weitere gute Option. Denken Sie daran, dass Sie lange auf signed begrenzt sind. Eigentlich ist die einfachste Option strtoull, die ebenfalls Standard ist.

+1

Atoll ist C99 nur ich denke, es ist in der Regel als Erweiterung für ANSI C aber nur in C99 garantiert. – dreamlax

+0

dreamlax, sieht aus als hättest du recht. –

0

Sind Sie sicher, dass fprintf einen LongLong als Parameter und nicht als Zeiger darauf verwenden kann? Es sieht so aus, als würde es Ihre LongLong in einen Int konvertieren, bevor Sie es übergeben.

1

Da Sie sagen, es druckt einen negativen Wert, muss es etwas anderes falsch sein, abgesehen von Ihrer Verwendung von atoi anstelle von strtoull. Ein Formatbezeichner %llu druckt einfach keinen negativen Wert.

Es sieht stark aus wie das Problem ist der fprintf Aufruf. Überprüfen Sie, ob Sie stdio.h enthalten haben und dass die Argumentliste tatsächlich im Quellcode enthalten ist.

0

Ich nehme an, das Problem ist, dass printf nicht% llu behandelt, wie Sie es denken. Es nimmt wahrscheinlich nur 32 Bits vom Stapel, nicht 64.

% llu ist nur Standard seit C99. vielleicht mag dein Compiler% LU besser?

0

Zur Verdeutlichung wurde die fprintf-Anweisung falsch kopiert (mein Fehler, sorry). Die fprintf Anweisung sollte tatsächlich gelesen:

fprintf(fd2, "volume = %llu\n", vold); 

Auch während zugegebenermaßen nachlässige die maximale Länge des das Array voltemp 9 Bytes (Ziffern), die innerhalb der Grenzen der 32-Bit-Ganzzahl ist gut.

Wenn ich diesen Code aus dem Programm herausziehe, es ist ein Teil davon und führe es in einem Testprogramm aus, bekomme ich das Ergebnis, das ich erwarten würde, was rätselhaft ist.

+0

Diese Klarstellung wäre sehr hilfreich als Teil der Frage selbst. Bitte bedenken Sie, dass Sie Ihre Frage bearbeiten können, anstatt sie hier als Antwort zu hinterlassen. –

0

Wenn voltemp jemals wirklich groß ist, müssen Sie strtoull, nicht atoi verwenden.