2010-10-14 20 views
7

Duplicar posibles:
pointer to a specific fixed addressCómo inicializar un puntero a una dirección de memoria específica en C++

una interesante discusión sobre esto comenzó here pero nadie ha sido capaz de proporcionar el C++ forma de hacer:

#include <stdio.h> 

int main(void) 
{ 
    int* address = (int *)0x604769; 
    printf("Memory address is: 0x%p\n", address); 

    *address = 0xdead; 
    printf("Content of the address is: 0x%p\n", *address); 

    return 0; 
} 

¿Cuál es la forma más adecuada de haciendo tal cosa en C++?

+3

Además de cambiar a las construcciones de C++, no hay una diferencia real en la forma en que lo haría en C++. – CashCow

Respuesta

18

En C++, siempre prefieren reinterpret_cast más de un C-yeso. Es tan feo que alguien inmediatamente detectará el peligro.

Ejemplo:

int* ptr = reinterpret_cast<int*>(0x12345678); 

Esa cosa me duelen los ojos, y me gusta.

+1

El código de muestra está en C y OP lo sabe. Él pregunta si hay una mejor manera de hacer lo mismo en C++. En un controlador de dispositivo, es posible que conozca la dirección absoluta en la que desea escribir. Recuerdo haber hecho este tipo de cosas en mis primeros días con MS-DOS para escribir directamente en la pantalla de la memoria. Con macros, por supuesto. – CashCow

+2

El acceso a registros de hardware a través de direcciones es una práctica común en sistemas integrados. Se definen como punteros constantes o se declaran usando '# define'. –

+1

¿Por qué fuiste a 'void *'? El código de OP quiere un puntero a un 'int' –

1

No hay forma estándar y portátil para hacerlo. Las formas no portátiles pueden incluir reinterpret_cast (someIntRepresentingTheAddress).

0

esto funcionará:

void *address=(void *) 0xdead; // But as mentioned, it's non-standard 

address=(void *) 0xdeadbeef; // Some other address 
+1

Si la pregunta es "¿cuál es el modo C++?", Entonces tomó una mala situación y empeoró yendo con 'void *' –

0

En C++, prefiero declarar los punteros como punteros constantes en un archivo de cabecera:

volatile uint8_t * const UART_STATUS_REGISTER = (uint8_t *) 0xFFFF4000; 

En el lenguaje C, esto por lo general se lleva a cabo utilizando una macro:

#define UART_STATUS_REGISTER ((volatile uint8_t * const) 0xFFFF4000) 

En el resto del código fuente, la dirección de memoria se referencia a través del nombre simbólico.

1

me gustaría añadir que se puede llamar al operador la colocación de nuevo si quieres un constructor de objetos que se llama cuando asignarlo a la dirección especificada:

int *pLoc = reinterpret_cast<int*>(0x604769); 
int *address = new (pLoc) int (1234); // init to a value 

Esto también se utiliza para los objetos de almacenamiento en caché de memoria. Crea un buffer y luego asignale un objeto.

unsigned char *pBuf = new unsigned char[sizeof(CMyObject) + alignment_size]; 
allign_buf(pBuf); 
CMyObject *pMyObj = new (pBuf) CMyObject; 
Cuestiones relacionadas