2010-07-31 7 views
16

Dado un puntero void, si quiero hacer que el puntero void apunte a x bytes, ¿cómo se hará esto mejor? ¿Hay alguna forma mejor que enviar un puntero char?Void Pointer Arithmetic

+0

He pedido una pregunta con un alcance más amplio de lo que estoy tratando de hacer aquí. Me gustaría saber si hay una mejor manera de hacerlo, la idea de emitir el vacío * a un char parece ser un truco para mí. http://stackoverflow.com/questions/3378090/custom-memory-manager – aCuria

+0

aCuria Compartí la sensación. De ahí las 2 preguntas que ya existen sobre esto, que he vinculado en mi respuesta. –

+0

Si tiene un programa en su mayoría C que simplemente usa algunas características de C++, el compilador se quejará de prácticamente cualquier vacío * en su programa. En mi opinión, el compilador está haciendo algo mal, no el programador. Por lo tanto, es necesaria una solución, no un rediseño completo del programa. – Minthos

Respuesta

14

¿Hay una manera mejor que el lanzamiento de un puntero de char?

No (salvo que tenga un char * en lugar de un void * para empezar, por lo que no tiene que echarlo en absoluto).

Si esto no es deseable o posible, entonces la única forma es:

ptr = static_cast<char *>(ptr) + offset; 

(Nota: si usted está haciendo este tipo de cosas en C++, generalmente no es una solución mucho mejor a menos. usted es un experto y ya descartó cualquier otra alternativa, le sugiero que publique una nueva pregunta que le pregunte si hay una forma mejor de hacer lo que está tratando de hacer!)

+0

Como sugirió, he publicado otra pregunta aquí http://stackoverflow.com/questions/3378090/custom-memory-manager – aCuria

2

Eche un vistazo a this question, y this question . Para resumir, la respuesta es convertir a char * en aritmética en un nivel de byte.

4

Dado un puntero de vacío, si quiero hacer que el puntero de vacío apunte a x bytes, ¿cómo se hará mejor? ¿Hay alguna forma mejor que enviar un puntero a un char?

Si tiene un void*, no sabe que "x bytes ahead" es una dirección válida. No sabe que la creación de dicho puntero no bloqueará su programa.

Y es por eso que no se puede hacer con void*.

Solo puede realizar operaciones aritméticas de punteros en punteros en una matriz. Y si tiene un puntero en una matriz, conoce el tipo de la matriz y puede usar el tipo de puntero equivalente.

Si desea algún tipo de "puntero de bytes" abstracto (por ejemplo, si se va a implementar un banco de memoria y la necesidad de apuntar a un desplazamiento en una memoria intermedia específica), se debe utilizar char* o unsigned char*, no void*.

2

Al realizar el compilador aritmético de puntero, se debe tener en cuenta lo que sabe sobre el tipo al que apunta el puntero.

Por ejemplo, si tiene un int *myint. A continuación, estas dos afirmaciones en realidad hacen lo mismo:

int a = *(myint+5); 

y

int a = myint[5]; 

en este caso myint+5 no significa "la dirección de Myint más 5", pero "la dirección de Myint más 5 * sizeof (int)) "

Por lo tanto, en el caso de un void *, el compilador no puede hacer ninguna suposición sobre qué debería significar void * + 5. Entonces, antes de usar un vacío *, te obliga a especificar cómo quieres usarlo.

+1

Podría suponer que sizeof (void) = 1 tiene gusto del compilador de C. Pero, por supuesto, eso sería demasiado fácil. – Minthos

-2

En diferencia a las demás personas que respondieron esta pregunta, me parece que un simple +x (sin conversión) es suficiente para acceder a la dirección x bytes antes de su puntero de vacío. Al compilador puede no gustarle, pero al menos en los casos que he usado esto, funcionó. Estoy usando g++ (gcc) ...

Así que mientras sepas lo que estás haciendo, no hay problema.

+1

La aritmética en punteros vacíos no está definida en C++. 'void' es un tipo incompleto, y la aritmética del puntero solo funciona para tipos completamente definidos. – Mat

-1

Aquí era mi problema

void *inputAudioBuffer; 

C++ no me dejaba hacer esto

UInt16 *inputBuffer = (UInt16 *)(inputAudioBuffer + inputBufferOffset); 

después de hacer un molde tipo que era capaz de hacerlo

UInt16 *inputBuffer = (UInt16 *)((UInt16 *) inputAudioBuffer + inputBufferOffset);