2

Say I have manually allocated a large portion of memory in C++, say 10 MB.

Say for the heck of it I want to store a few bits around the middle of this region.

How would I get at the memory at that location?

The only way I know of accessing raw memory is using array notation.

Cody Smith
  • 2,732
  • 3
  • 31
  • 43
  • Which platform? An OS or an embedded device? It might matter. – corazza Jan 14 '13 at 18:55
  • 1
    array notation sounds good to me. alternatively, you could do some pointer arithmetics, like `int *data = malloc(N); int *middle = data + X` – Andreas Grapentin Jan 14 '13 at 18:56
  • 1
    [Here](http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c) are ways to actually do the toggle of a single bit. – Celeritas Jan 14 '13 at 18:57

5 Answers5

9

And array notation works well for that, as the allocated memory can be seen as a large array.

// Set the byte in the middle to `123`
((char *) memory_ptr)[5 * 1024 * 1024] = 123;

I typecast to a char pointer in case the pointer is of another type. If it's already a char pointer then the typecast isn't needed.


If you only want to set a single bit, see the memory as a giant bit field with 80 million separate bits. To find the bit you want, say bit number 40000000, you must first find the byte it's in and then the bit. This is done with normal division (to find the char) and modulo (to find the bit):

int wanted_bit = 40000000;

int char_index = wanted_bit / 8;  // 8 bits to a byte
int bit_number = wanted_bit % 8;

((char *) memory_ptr)[char_index] |= 1 << bit_number;  // Set the bit
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
7

Array notation is just another way of writing pointers. You can use that, or use pointers directly like so:

char *the_memory_block = // your allocated block.
char b = *(the_memory_block + 10); // get the 11th byte, *-operator is a dereference.
*(the_memory_block + 20) = b; // set the 21st byte to b, same operator.

memcpy, memzero, memmove, memcmp and others may also be very useful, like this:

char *the_memory_block = // your allocated block.
memcpy(the_memory_block + 20, the_memory_block + 10, 1);

Of course this code is also the same:

char *the_memory_block = // your allocated block.
char b = the_memory_block[10];
the_memory_block[20] = b;

And so is this:

char *the_memory_block = // your allocated block.
memcpy(&the_memory_block[20], &the_memory_block[10], 1);

Also, one is not safer then the other, they are completely equivalent.

rmhartog
  • 2,293
  • 12
  • 19
  • Char is used as the pointer type because chat is equivalent to one byte, right? – Cody Smith Jan 14 '13 at 19:10
  • 1
    Yes, but you are in no way restricted to character pointers. You can point to **almost** anything. – rmhartog Jan 14 '13 at 19:12
  • 1
    A warning about `memcpy`, you have to be careful not to copy overlapping areas, i.e. when the distance between the source and the destination is less than the size you copy. In that case `memmove` is needed. – Some programmer dude Jan 14 '13 at 19:27
2

I think the array notation would be your answer... You can use the bitshift operators << and >> with AND and OR bitmasks to access specific bits.

Stephen Hewlett
  • 2,415
  • 1
  • 18
  • 31
1

You can use array notation, or you can use pointer arithmetic:

char* buffer = new char[1024 * 1024 * 10];

// copy 3 bytes to the middle of the memory region using pointer arithmetic
//
std::memcpy(buffer + (1024 * 1024 * 5), "XXX", 3); 
Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
1

C/C++, arrays are treated as pointers to their first elements. So, an array name is nothing but an alias to its first element:

*pName is equivalent pName[0]

And then:

*(pName+1) == pName[1];
*(pName+2) == pName[2];

And so on. Parenthesis are used to avoid precedence issues. Never forget using them.

After compilation, both ways will behave the same. I do prefer brackets notation for readability.

reimorster
  • 31
  • 1
  • 5