How to initialize a pointer to a specific memory address in C++

42,269

Solution 1

In C++, always prefer reinterpret_cast over a C-cast. It's so butt ugly that someone will immediately spot the danger.

Example:

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

That thing hurts my eyes, and I like it.

Solution 2

There is NO standard and portable way to do so. Non-portable ways may include reinterpret_cast(someIntRepresentingTheAddress).

Solution 3

This will work:

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

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

Solution 4

In C++, I prefer to declare the pointers as constant pointers in a header file:

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

In the C language, this is usually implemented using a macro:

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

In the rest of the source code, the memory address is referenced via the symbolic name.

Solution 5

I would add that you can call the placement operator for new if you want an objects constructor called when assigning it at the specified address:

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

This is also used for memory caching objects. Create a buffer and then assign an object to it.

unsigned char *pBuf = new unsigned char[sizeof(CMyObject) + alignment_size];
allign_buf(pBuf);
CMyObject *pMyObj = new (pBuf) CMyObject;
Share:
42,269
karlphillip
Author by

karlphillip

Helpful posts: How much research effort is expected of Stack Overflow users? How to create a Minimal, Reproducible Example How does accepting an answer work? Answering technical questions helpfully Achievements: 1st                  1st                  2nd

Updated on October 23, 2020

Comments

  • karlphillip
    karlphillip over 3 years

    An interesting discussion about this started here but no one have been able to provide the C++ way of doing:

    #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;
    }
    

    What is the most appropriate way of doing such a thing in C++?

  • CashCow
    CashCow over 13 years
    The sample code is in C and the OP knows it is. He is asking if there is a better way to do the same in C++. In a device driver you may well know the absolute address you wish to write to. I remember doing this kind of thing in my early days with MS-DOS to write directly to the memory screen. With macros - of course.
  • Thomas Matthews
    Thomas Matthews over 13 years
    Accessing hardware registers via addresses is common practice in embedded systems. They are either defined as constant pointers or declared using #define.
  • John Dibling
    John Dibling over 13 years
    If the question is "what is the C++ way" then you took a bad situation and made it worse by going with void*
  • John Dibling
    John Dibling over 13 years
    Why did you go to void*? OP's code want a pointer to an int
  • Coincoin
    Coincoin over 13 years
    @John: Good point. Changed it. Thanks.
  • David Thornley
    David Thornley over 13 years
    @CashCow: Sure - but you're doing implementation-specific casting no matter what, and reinterpret_cast is the C++ way of doing it. It's better because it's easier to find, and flags this as a potentially unsafe operation should anybody try porting this.
  • Lokanath
    Lokanath over 7 years
    @Coincoin what if the address is already occupied?
  • That Realty Programmer Guy
    That Realty Programmer Guy over 5 years
    don't even listen to them, void* are underappreciated due to fear lol. this is a purist answer in a way
  • Amir Kirsh
    Amir Kirsh almost 4 years
    Is there a need, since C++17, to use std::launder? like that: int* ptr = std:: launder(reinterpret_cast<int*>(0x12345678)); This relates to @Lokanath comment above: "what if the address is already occupied?", or taken a bit differently: what if another live pointer already points there? Then std::launder becomes important I believe.