2011-08-23 13 views
9

Sto scrivendo del codice e sto ricevendo uno strano errore: il mio ciclo for non sembra uscire quando l'istruzione della condizione diventa falsa. Il codice è il seguente:Per il ciclo che non termina in 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'; 
    } 
} 

Quando si esegue questo codice con un ingresso esempio, (il Py_UNICODE * punti tampone all'oggetto interno unicode pitone fornito con u "esempio") ottengo il seguente output:

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 

... 

Il ciclo non si chiude fino a quando non si verifica un arresto anomalo dell'interprete python dal codice (I am wrapping ac module for python).

I file di stampa sono stati inseriti per il debug.

sto compilando questo su Mac OSX 10.6, qui ci sono i comandi che sto usando per compilare:

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 ./ 

Come potete vedere stanno collegando nel quadro che sto facendo l'involucro Python per. Questo non è un problema in quanto posso chiamare le funzioni bene che usano il framework collegato, proprio quando chiamo la funzione che usa la funzione helper mostrata sopra, ottengo il problema.

Sono stupido qui e sto facendo qualcosa di molto sbagliato o qualcosa di sbagliato nel compilatore? Qualsiasi aiuto sarebbe molto apprezzato!

+0

cosa è sizeof (Py_ssize_t)? – hari

+0

Insetto davvero strano! Penso che darei un'occhiata al codice assembly per vedere cosa ha fatto al loop. Penso che il compilatore abbia rovinato qualcosa. Forse la definizione del tipo di Py_ssize_t confonde in qualche modo? –

risposta

14

credo che questo ha soprattutto a che fare con il numero precission. Se Py_ssize_t è un tipo a 64 bit, è possibile che sia del formato: 0xffffffff00000008 (forse perché un valore di calcolo precedente che implica numeri di precisione errati o missaggio firmato con calcoli senza segno). Considerato come int (32 bit), il risultato è 8, ma quando viene considerato come valore a 64 bit, produce un numero negativo molto piccolo (firmato) o un numero molto grande positivo (senza segno). Prova a modificare le espressioni wprintf per scrivere un decimale lungo (%ld) e vedere che cosa viene stampato, o eseguire il debug del codice con gdb per vedere il numero nella sua dimensione reale.

+1

Quando ho modificato wprintf per utilizzare% ld, il numero che ho ottenuto era 4294967303 che corrisponde a 0x100000007. Buona pesca! – ifross

5

Puoi provare a utilizzare un numero i e un numero strLength?

Non so Py_ssize_t tipo, ma il cast implicito con l'%d in printf potrebbe nascondere il problema

+0

Ha funzionato! (beh, ho lanciato la strLength su un nuovo int e ho dichiarato io come int) – ifross

+0

@ user980127: fai attenzione a quel 'fix' - è un'indicazione che chiunque sta chiamando 'wstrcpy_from_Py_UNICODE()' sta passando 'strLength' in modo non corretto (o forse che dovresti copiare una stringa enorme). La causa principale del tuo problema è probabilmente "a monte": dovresti prestare attenzione a questo invece di mascherare il problema all'interno di "wstrcpy_from_Py_UNICODE()". –

3

Che cosa è un Py_ssize_t?

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

altro che chiamare wprintf con un char* (una volta), si sta utilizzando il "%d" identificatore per i valori di tipo Py_ssize_t