2011-01-13 164 views
8

私は、ネットワークパケットの長さに基づいて反復するforループを作成しようとしています。 APIには、event.packet-> dataLengthによって変数(size_t)が存在します。私は0からevent.packet-> dataLength - 7 iterates iteratesするたびに私は10増加する反復したいが、私は問題の世界を抱えています。size_tを整数に変換する(C++)

私は解決策を探しましたが、有用なものは何も見つかりませんでした。 size_tをunsigned intに変換しようとしましたが、それを使って算術演算を行っていましたが、残念ながらそれは機能しませんでした。基本的に私が望むすべてはこれです:

for (int i = 0; i < event.packet->dataLength - 7; i+=10) { } 

私は私の変換時にこのまたは試みのような何かをするたびに私<#部分は、膨大な数ですが。彼らは実際の数値を出力するために "%u"を使ったAPIのチュートリアルでprintfステートメントを与えましたが、まだunsigned intに変換してもそれは間違っています。私はここからどこに行くべきか分からない。どのような助けが大いに評価されるでしょう:)

+3

考えてみましょう: 'static_cast ( - 1)'の値は何ですか? 'event.packet-> dataLength'が7より小さいとどうなりますか? – genpfault

+0

なぜ 'i'も' size_t'できないのですか?また、長さが常に7 mod 10に等しくなければ、これは試行する非常に特殊なループです。 – OrangeDog

+0

'event.packet-> dataLength'を' int'にキャストしようとしましたか? – Dawson

答えて

4

iのタイプを変更してみませんか?

for (size_t i = 0; i < event.packet->dataLength - 7; i+=10) { } 

同じ種類の変数をすべて一緒に使用するようにしてください。キャストは避けるべきです。

size_tの書式指定子はC++ 03ではありません。できる最大の符号なし整数型にキャストして印刷する必要があります。 (C++ 0xのsize_tの書式指定子は%zuです)。しかし、あなたはとにかくprintfを使用すべきではありません。

std::cout << i; // print i, even if it's a size_t 

ストリームはより冗長かもしれないが、彼らはより多くのタイプ安全だと何かを暗記する必要はありません。

実際のループロジックに欠陥がある可能性があることに注意してください。 (dataLength - 7が負の場合、genpfaultノートとは何ですか?)

+0

これは、 'dataLength - 7'が負の場合には役に立ちません。 –

+0

@David:いいえ、それは私がそれを言及した理由ではありません。意図を知らなくても修正が何であるかを言うのは難しい。 – GManNickG

+0

私はsize_tを作ってみましたが、すでにうまくいきませんでした。 – JeanOTF

1

dataLength> = 7ですか? dataLength-7の結果が負の場合、それを符号なしと解釈すると、結果は非常に大きな整数になります。

0

iはsize_tを使用します。

printfの場合、C99を使用していない場合は、C90のみをunsigned longまたはunsigned long longにキャストします。例えば:

for (size_t i = 0; i < 10; ++i) 
     //printf("%llu\n", (unsigned long long)i); 
     printf("%lu\n", (unsigned long)i); 

そうでない場合event.packet->dataLength < 7場合は、最初に確認する必要があります%のZU

0

を使用しています。今度は、7より小さい場合は、0より小さい値を符号なしとして使用します。 0 = 0x00000000; -1 = 0-1 = 0xFFFFFFFF。

再び、チェック:

if (event.packet->dataLength < 7) { 
    ... 
} else { 
    for (size_t i = 0; i < event.packet->dataLength - 7; i+=10) { } 
} 
2

が署名した算術演算ですべてを行います。試してみてください:あなたは負でもよい値で符号なし演算を使用して、そして<のような比較演算子を使用して起動したら、あなたが困っている

for (int i = 0; i < int(event.packet->dataLength) - 7; i+=10) { } 

。物事を維持する方がはるかに簡単です。

+0

ええ、元のコメントを削除しなければならず、標準保証された動作に関してはあまりにも多くのことを考えました。 2の補数マシン上で、非迂回コンパイラ、すなわち*実際には*で、上記は動作します。しかし、おそらく巨大な符号なしの値を 'int'に変換することは正式にUBです。ですから、かっこを修正するのが一番です。乾杯、 –

+0

@ Alf P. Steinbach:ありがとう - あなたのコメントの後でさえ、あなたが意味するものを理解するのに瞬間がかかったので、それは単にタイプミスではありませんでした。 –

0

「私がこのようなことをしたり、自分の変換を試みるたびに、私は<#部分が膨大な数です」

これは、元のパケット長が7より小さい(7を引いている)ことを示します。

1つの脆弱性は、実践的に十分な大きさの符号付き整数型を使用することです。標準ライブラリは、その目的でptrdiff_tを提供します。以下のような、

#include <stdlib.h> // Not sure, but I think it was this one. 

typedef ptrdiff_t Size; 
typedef Size   Index; 

void foo() 
{ 
    // ... 
    for(Index i = 0; i < Size(event.packet->dataLength) - 7; i += 10) 
    { 
     // ... 
    } 
} 

より面倒な問題を回避するには、サイズが少なくとも7

乾杯& HTHであることをチェックifに全部を埋め込むことである。、

0

​​は、符号なしを返すのでタイプsize_t

1)インデックス可変型としてsize_tを使用してください。

2)確実な数学はアンダーフローしません。 @beldaz。​​から7を引くのではなく、7をiに加える。

// for (int i = 0; i < event.packet->dataLength - 7; i+=10) { } 
for (size_t i = 0; i + 7 < event.packet->dataLength; i += 10) { } 
関連する問題