I was interested in accessing portions of memory I had allocated to get a better understanding of things, lets say I allocate 10 bytes with malloc
and printf("%p", &foo)
returns 0xff0a
, would I be able to allocate 0xff0a->0xff1a
(my hexadecimal math is bad at the moment) and access any one of those individual bytes?
I think I recall being used the keyword volatile
along with a memory address for this, I am not sure what that code was able to do though..
I guess what I mean is how do I access a random byte in开发者_运维知识库 memory, cast as a char or integer that I can store in a pointer for accessing later on.
I'll assume you want to access a single byte from a multi-byte type such as an int or a short. The common idiom is to cast the address to a char* and deference that like so:
#include <stdio.h>
int main(void)
{
int foo = 0xDEADBEEF;
int i;
for (i = 0; i < 4; i++) {
printf("byte %d of foo is x%02X\n", i, *((unsigned char*)&foo + i));
}
return 0;
}
Output
$ ./a.out
byte 0 of foo is xEF
byte 1 of foo is xBE
byte 2 of foo is xAD
byte 3 of foo is xDE
Note The reason it looks backwards is due to x86 being little endian
printf("%p", &foo)
prints the address of the pointer variable foo
, not the address contained in foo
(which is the one that came from malloc
). You actually want:
printf("%p", (void *)foo);
If you wish to access the 10 bytes in memory pointed to by foo
, you can simply use:
char *p = foo;
and then access p[0]
through p[9]
.
If you allocate 10 bytes from 0xff0a
, the address range is: 0xff0a
to 0xFF14
.
volatile
forces the compiler to grab the stored value at that location every time. This has uses in hardware programming and multi-threaded applications.
This example stores the address of the int x into the pointer p:
int x = 5;
int * p = &x; //assign address of (operator &) x into a pointer
printf("%d\n", *p); // will display 5
You may want to use a union in order to always apply the same bunch of code to loop over the bytes area of your variable. The member 'byte' will always point to the same address as the others. You can include it into a struct in order to keep the size along with the union. A the end, you just call a function to print out or check the content of a bunch of memory...
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
union byteMap {
char* addressString;
void* addressInt;
unsigned char* byte;
};
struct structByteMap {
size_t size;
union byteMap map;
};
int main (int argc, char* argv[]) {
struct structByteMap map;
if (argc > 1) {
int temp = strtoimax(argv[1], NULL, 10);
map.map.addressInt = &temp;
map.size = sizeof(int);
} else {
map.map.addressString = "HELLO, YES HELLO";
map.size = strlen(map.map.addressString);
}
for (int i = 0; i < map.size; i++) {
printf("byte %d of param is x%02X\n", i, *(map.map.byte + i));
}
}
精彩评论