Pregunta

Dado este campo:

char lookup_ext[8192] = {0}; // Gets filled later

Y esta declaración:

unsigned short *slt = (unsigned short*) lookup_ext;

¿Qué sucede detrás de escena?

lookup_ext[1669] devuelve 67 = 0100 0011 (C), lookup_ext[1670] devuelve 78 = 0100 1110 (N) y lookup_ext[1671] devuelve 68 = 0100 0100 (D);sin embargo, slt[1670] devuelve 18273 = 0100 0111 0110 0001.

Estoy intentando migrar esto a C#, así que además de una manera fácil de solucionarlo, también me pregunto qué sucede realmente aquí.Ha pasado un tiempo desde que usé C++ con regularidad.

¡Gracias!

¿Fue útil?

Solución

La declaración que muestra no arroja un carácter a un corto sin firmar, arroja un puntero a un personaje a un puntero a un corto sin firmar.Esto significa que las conversiones aritméticas habituales de los datos apuntados no se producirán y que los datos de caracteres subyacentes simplemente se interpretarán como cortos sin firmar cuando se acceda a ellos a través del slt variable.

Tenga en cuenta que sizeof(unsigned short) es poco probable que sea uno, por lo que slt[1670] no necesariamente corresponderá a lookup_ext[1670].Es más probable -si, por ejemplo, sizeof(unsigned short) es dos - para corresponder a lookup_ext[3340] y lookup_ext[3341].

¿Sabes por qué el código original utiliza este alias?Si no es necesario, podría valer la pena intentar hacer que el código C++ sea más limpio y verificar que el comportamiento no haya cambiado antes de migrarlo.

Otros consejos

Si entiendo correctamente, la conversión de tipo convertirá una matriz de caracteres de tamaño 8192 en una matriz int corta de tamaño medio, que es 4096.

Entonces no entiendo lo que estás comparando en tu pregunta. slt [1670] debe corresponder a lookup_ext [1670 * 2] y lookup_ext [1670 * 2 + 1].

Bueno, esta declaración

char lookup_ext[8192] = {0}; // Gets filled later

Crea una matriz localmente o no localmente, dependiendo de dónde ocurra la definición. Inicializándolo así, con un inicializador agregado inicializará todos sus elementos a cero (el primero explícitamente, los restantes implícitamente). Por lo tanto, me pregunto por qué su programa genera valores distintos de cero. A menos que el relleno ocurra antes de la lectura, entonces eso tiene sentido.

unsigned short *slt = (unsigned short*) lookup_ext;

Eso interpretará los bytes que componen la matriz como objetos cortos sin signo cuando lea desde el objetivo de ese puntero. Hablando estrictamente, lo anterior es un comportamiento indefinido, porque no puede estar seguro de que la matriz esté alineada adecuadamente, y leería desde un puntero que no apunta al tipo del tipo puntiagudo original (unsigned char & Lt; - < !> gt; sin signo corto). En C ++, la única forma portátil de leer el valor de algún otro pod (datos antiguos simples. Esas son todas las estructuras y tipos simples que también son posibles en C (como short), en términos generales) es mediante el uso de funciones de biblioteca como memcpy o memmove.

Entonces, si lee *slt arriba, interpretaría los primeros sizeof(*slt) bytes de la matriz e intentaría leerlo como corto sin signo (que se llama type pun).

Cuando haces " unsigned short slt = (unsigned short ) lookup_ext; " ;, el no. de bytes equivalentes al tamaño de (unsigned short) se recogen de la ubicación dada por lookup_ext y se almacenan en la ubicación señalada por slt. Como el corto sin signo sería de 2 bytes, los primeros dos bytes de lookup_ext se almacenarían en la ubicación proporcionada por slt.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top