2011-08-23 12 views
9

Estoy escribiendo un código y obtengo un error extraño: mi bucle for no parece salir cuando el enunciado de condición se convierte en falso. El código es como sigue:Para el bucle que no termina en 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'; 
    } 
} 

Cuando se ejecuta este código con una entrada de ejemplo, (El Py_UNICODE * puntos tampón para el objeto interno Unicode pitón hecho con u "ejemplo") consigo el siguiente resultado:

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 

... 

El bucle no se cierra hasta que el intérprete de python que ejecuta el código desde (estoy envolviendo el módulo de CA para python) falla.

Los printf se colocaron para la depuración.

soy compilar esto en Mac OS X 10.6, aquí están los comandos que estoy utilizando para compilar:

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

Como se puede ver que estoy de vínculos de la estructura que estoy haciendo el envoltorio de Python para. Esto no es un problema ya que puedo llamar a las funciones que usan el framework vinculado, justo cuando llamo a la función que usa la función de ayuda mostrada arriba obtengo el problema.

¿Estoy siendo estúpido aquí y estoy haciendo algo muy básico o algo malo con el compilador? ¡Cualquier ayuda sería muy apreciada!

+0

¿Qué es sizeof (Py_ssize_t)? – hari

+0

¡Error muy raro! Creo que echaré un vistazo al código de ensamblado para ver qué hizo con el ciclo. Creo que el compilador arruinó algo. Tal vez la definición de tipo de Py_ssize_t es confusa de alguna manera? –

Respuesta

14

creo que esto sobre todo tiene que ver con el número de precision. Si Py_ssize_t es un tipo de 64 bits, puede tener la forma: 0xffffffff00000008 (tal vez debido a un valor de cálculo anterior que implica números de precisión incorrectos, o mezcla firmada con cálculos sin firmar). Cuando se lo considera int (32 bits), su resultado es 8, pero cuando se considera como un valor de 64 bits, arroja un número negativo muy pequeño (firmado) o un número positivo muy grande (sin signo). Intente cambiar las expresiones wprintf para escribir un decimal largo (%ld) y vea lo que se imprime, o depure su código con gdb para ver el número en su tamaño real.

+1

Cuando cambié wprintf para usar% ld, el número que obtuve fue 4294967303 que corresponde a 0x100000007. ¡Buena atrapada! – ifross

5

¿Puedes intentar usar un int i y un int strLength?

No sé Py_ssize_t tipo, pero la conversión implícita con el %d en printf podría ocultar el tema

+0

¡Eso funcionó! (Bueno, echo el strLength a un nuevo int y lo declaro como int) – ifross

+0

@ user980127: ten cuidado con ese 'arreglo' - es una indicación de que quienquiera que esté llamando 'wstrcpy_from_Py_UNICODE()' está pasando 'strLength' incorrectamente (o tal vez que se supone que debes copiar una cadena enorme). La causa raíz de su problema probablemente sea 'aguas arriba'; debe prestar atención a eso en lugar de enmascarar el problema dentro de 'wstrcpy_from_Py_UNICODE()'. –

3

¿Qué es 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)); 

Aparte de llamar wprintf con un char* (una vez), que está utilizando el especificador "%d" de valores de tipo Py_ssize_t

Cuestiones relacionadas