2011-08-23 4 views
9

私はいくつかのコードを書いています。私は奇妙なエラーが発生しています。私のforループは、条件文が偽になったときに終了しないようです。コードは以下の通りである:forループはCで終了しません

static void wstrcpy_from_Py_UNICODE(Py_UNICODE *inBuf, Py_ssize_t strLength, wchar_t **outBuf) 
{ 
    if (strLength == 0) *outBuf = NULL; 
    else 
    { 
     Py_ssize_t i; 
     wprintf(L"String Length: %d\n", strLength); 
     *outBuf = (wchar_t *)malloc (sizeof (wchar_t) * (strLength +1)); 
     for (i=0; i < strLength; i++) 
     { 
      wprintf("i:%d, strLength:%d\n", i, strLength); 
      (*outBuf)[i] = (wchar_t)(inBuf[i]); 
      wprintf(L"i < strLength: %d\n\n", i < strLength); 
     } 
    /* Make sure new string is zero terminated */ 
    (*outBuf)[i] = L'\0'; 
    } 
} 

例えば入力、(U「例」で作られた内部のUnicode PythonオブジェクトへのPy_UNICODE *バッファ・ポイント)と、このコードを実行すると、私は次の出力を取得:

String Length: 7 
i:0, strLength: 7 
i < strLength: 1 

i:1, strLength: 7 
i < strLength: 1 

i:2, strLength: 7 
i < strLength: 1 

i:3, strLength: 7 
i < strLength: 1 

i:4, strLength: 7 
i < strLength: 1 

i:5, strLength: 7 
i < strLength: 1 

i:6, strLength: 7 
i < strLength: 1 

i:7, strLength: 7 
i < strLength: 1 

i:8, strLength: 7 
i < strLength: 1 

... 

コードが実行されているPythonインタプリタ(Python用のacモジュールをラップしています)がクラッシュするまで、ループは終了しません。

printfはデバッグのために置かれました。私は、Mac OSX 10.6上でこれをコンパイルしています

、ここで私がコンパイルに使用していたコマンドは次のとおりです。

gcc -c source.c -I/usr/include/python2.6 -I/usr/lib/python2.6 
ld -bundle -flat_namespace -undefined suppress -o out.so source.o -F./ -framework some_framework -macosx_version_min 10.6 -rpath ./ 

あなたは私がのためのPythonラッパーを作っていますフレームワークにリンクしています見ることができるように。上記のヘルパー関数を使用する関数を呼び出すときに、リンクされたフレームワークを使用する関数をうまく呼び出すことができれば問題はありません。

私はここで愚かで、何か非常に基本的なやり方を間違っているか、コンパイラに何か間違っていますか?どんな助けでも大歓迎です!

+0

sizeof(Py_ssize_t)とは何ですか? – hari

+0

本当に奇妙なバグ!ループに何があったのかを知るためにアセンブリコードを覗いてみたいと思います。私はコンパイラが何かをねじ込んだと思う。多分Py_ssize_tの型定義は何とか混乱しているでしょうか? –

答えて

14

タイプPy_ssize_tの値に対して"%d"指定子を使用している私は、これは主に番号precissionとしなければならないと思います。 Py_ssize_tが64ビットタイプの場合は0xffffffff00000008である可能性があります。不正確な精度の数値が含まれる前回の計算値、または符号なし計算とのミキシングが原因である可能性があります。 int(32ビット)と見なされたときの結果は8ですが、64ビット値と見なすと、非常に小さな負数(符号付き)または非常に大きな正数(符号なし)が得られます。 wprintfの式を変更して、長い小数点(%ld)を書いて、何が印刷されているかを確認するか、gdbでコードをデバッグして数字を実際のサイズで表示してみてください。

+1

wprintfを%ldを使用するように変更したとき、私が得た数は4294967303で0x100000007に相当します。いいキャッチ! – ifross

5

int iとint strLengthを使用できますか?

私はPy_ssize_tタイプを知らないが、printf%dとの暗黙のキャストは問題Py_ssize_t

+0

それはうまくいった! (よくstrLengthを新しいintにキャストし、intとして宣言しました) – ifross

+0

@ user980127: '修正'に注意してください - 'wstrcpy_from_Py_UNICODE()'を呼んでいる人が 'strLength'を間違って渡しているあなたは巨大な文字列をコピーしているはずです)。あなたの問題の根本的な原因はおそらく '上流'です - あなたは 'wstrcpy_from_Py_UNICODE()'の中の問題を隠すのではなく、それに注意を払うべきです。 –

3

を隠すのでしょうか? char*(1回)でwprintfを呼び出す以外

printf("sizeof (int) is %d\n", (int)sizeof (int)); 
printf("sizeof (Py_ssize_t) is %d\n", (int)sizeof (Py_ssize_t)); 

、あなたが

関連する問題