How to Allocate a Specific Memory Address Using Pointers in C++

How to assign pointer address manually in C programming language?

Like this:

void * p = (void *)0x28ff44;

Or if you want it as a char *:

char * p = (char *)0x28ff44;

...etc.

If you're pointing to something you really, really aren't meant to change, add a const:

const void * p = (const void *)0x28ff44;
const char * p = (const char *)0x28ff44;

...since I figure this must be some kind of "well-known address" and those are typically (though by no means always) read-only.

How to assign a specific memory address to a pointer?

Assuming this is a valid writable on your process memory address and by "an integer" you meant an int:

*reinterpret_cast<int*>(0x8f820dae) = 2;

Note that this will write the value 2 (0x00000002) to the address 0x8f820dae (considering x86). Change the <int> type-parameter if you want to write a different numbers of bytes (i.e. sizeof(int) bytes will be written at the memory address).

Can I Allocate a specific memory address using pointers in c++?

Allocating a specific address in your process's address space is a bit tricky and platform-specific. On Unix systems, mmap() is probably the closest you're going to get. The Windows equivalent is VirtualAlloc(). There are, of course, no guarantees since the address might already be in use.

Writing to a specific address is trivial:

char *p = (char*)0x25D4C3FA;
*p = 4;

I assume you have good reasons to want to do that.

assigning a pointer a specific memory location in C

Pointers are just numbers corresponding to a memory location. You can do math on them, but it works a bit differently than normal. It's called pointer arithmetic.

Adding 1 to a pointer moves it forward in memory not 1 byte, but the size of whatever it's pointing at. If it's a char * it will move 1 byte. If it's a int * it will move 4 or 8 bytes depending on the size of your integers. If its a 50 byte struct, it will move forward 50 bytes.

So all you need to do is add 1 to your pointer.

#include <stdio.h>

struct example {
char string[50];
};

int main() {
struct example foo;
struct example *bar = &foo + 1;

printf("%p %p\n", &foo, bar);
}

$ ./test
0x7fff5897b4a0 0x7fff5897b4d2

...except now bar is pointing to unallocated memory. If you try to use it, it will be undefined behavior.

If you want to make two structs adjacent to each other in memory that you can actually use, make an array.

#include <stdio.h>

struct example {
char string[50];
};

int main() {
struct example list[2];

printf("%p %p\n", &list[0], &list[1]);
}

$ ./test
0x7fff5ba21470 0x7fff5ba214a2

Or if you're using heap memory...

#include <stdio.h>
#include <stdlib.h>

struct example {
char string[50];
};

int main() {
struct example *list = malloc( 2 * sizeof(struct example) );

printf("%p %p\n", &list[0], &list[1]);
}

Accessing specific memory locations in C

Common C compilers will allow you to set a pointer from an integer and to access memory with that, and they will give you the expected results. However, this is an extension beyond the C standard, so you should check your compiler documentation to ensure it supports it. This feature is not uncommonly used in kernel code that must access memory at specific addresses. It is generally not useful in user programs.

As comments have mentioned, one problem you may be having is that your operating system loads programs into a randomized location each time a program is loaded. Therefore, the address you discover on one run will not be the address used in another run. Also, changing the source and recompiling may yield different addresses.

To demonstrate that you can use a pointer to access an address specified numerically, you can retrieve the address and use it within a single program execution:

#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>

int main(void)
{
// Create an int.
int x = 0;

// Find its address.
char buf[100];
sprintf(buf, "%" PRIuPTR, (uintptr_t) &x);
printf("The address of x is %s.\n", buf);

// Read the address.
uintptr_t u;
sscanf(buf, "%" SCNuPTR, &u);

// Convert the integer value to an address.
int *p = (int *) u;

// Modify the int through the new pointer.
*p = 123;

// Display the int.
printf("x = %d\n", x);

return 0;
}

Obviously, this is not useful in a normal program; it is just a demonstration. You would use this sort of behavior only when you have a special need to access certain addresses.

C programming pointer, bytes and memory allocation have 8 question

• how can i access the first byte of this int pointer? [question01]

Generally, it is preferable to use unsigned char rather than char to access arbitrary bytes, so let’s do that.

After unsigned char *ptr = #, ptr is a pointer to unsigned char, and you could access the first byte of the int with *ptr or ptr[0], as in printf("The first byte, in hexadecimal, is 0x%02hhx.\n", *ptr);.

If instead you have int *ptr = #, there is no direct way to access the first byte. ptr here is a pointer to an int, and, to access an individual byte, you need a pointer to an unsigned char or other single-byte type. You could convert ptr to a pointer to unsigned char, as with (unsigned char *) ptr, and then you can access the individual byte with * (unsigned char *) ptr.

• is there a way to see the bites inside the of the first byte([01])? [question02]

The C standard does not provide a way to display the individual bits of a byte. Commonly programmers print the values in hexadecimal, as above, and read the bits from the hexadecimal digits. You can also write your own routine to write binary output from a byte.

• where does the pointer save the address? does it have to allocate a memory space in the ram to save whe address such as 0x233828ff21 and if so this(0x233828ff21) address requires a lot of bytes? [question03]

A pointer is a variable like your other int and char variables. It has space of its own in memory where its value is stored. (This model of variables having memory is used to specify the behavior of C programs. When a program is optimized by a compiler, it may change this.)

In current systems, pointers are commonly 32 or 64 bits (four or eight 8-bit bytes), depending on the target architecture. You can find out which with printf("The size of a 'char *' is %zu bytes.\n", sizeof (char *));. (The C standard allows pointers of different types to be different sizes, but that is rare in modern C implementations.)

• where does this int pointer stores it's type length (4bytes)? [question05]

The compiler knows the sizes of pointers. The pointer itself does not store the length of the thing it is pointing to. The compiler simply generates appropriate code when you use the pointer. If you use *ptr to get the value that a pointer points to, the compiler will generate a load-byte instruction if the type of ptr is char *, and it will generate a load-four-byte instruction of the type of ptr is int * (and int is four bytes in your C implementation).

• what happens if i declare a type with longer byte memory allocation such as long long * ptr = # [01][02][00][00][00][00][00][00] since i am pointing a long long to a 4 byte int, can those 4 last already been allocated by another program and in use? can i read it? [question06]

When long long is an eight-byte integer, and you have a long long *ptr that is pointing to a four-byte integer, the C standard does not define the behavior when you attempt to use *ptr.

In general-purpose multi-user operating systems, the memory after the int cannot be allocated by another program (unless this program and the other program have both arranged to share memory). Each process is given its own virtual address space, and their memory is kept separate.

Using this long long *ptr in your program may access memory beyond that of the int. This can cause various types of bugs in your program, including corrupting data and alignment errors.

• binary are only 0 and 1 and whether one of those(0 or 1) is called a bite? [question07]

One binary digit is a “bit”. Multiple binary digits are “bits”.

The smallest group of bits that a particular computer operates on as a unit is a “byte”. The size of a byte can vary; early computers had bytes of different sizes. Modern computers almost all use eight-bit bytes.

If your program includes the header <limits.h>, it defines a macro named CHAR_BIT that provides the number of bits in a byte. It is eight in almost all modern C implementations.

• one byte is 8 bits right? why am i getting 16 bits 0000000000000001 when converting the number 1 in this website (https://www.rapidtables.com/convert/number/decimal-to-binary.html) shouldn't it be 8? [question08]

The web site is not merely converting to one byte.

It seems to show at least 16 bits, choosing the least of 16, 32, or 64 bits that the value fits in as a signed integer type.

How can I allocate memory and return it (via a pointer-parameter) to the calling function?

You want to use a pointer-to-pointer:

void someFunction (int **data) {
*data = malloc (sizeof (int));
}

void useData (int *data) {
printf ("%p", data);
}

int main () {
int *data = NULL;

someFunction (&data);

useData (data);

return 0;
}

Why? Well, you want to change your pointer data in the main function. In C, if you want to change something that's passed in as a parameter (and have that change show up in the caller's version), you have to pass in a pointer to whatever you want to change. In this case, that "something you want to change" is a pointer -- so to be able to change that pointer, you have to use a pointer-to-pointer...

Note that on top of your main problem, there was another bug in the code: sizeof(data) gives you the number of bytes required to store the pointer (4 bytes on a 32-bit OS or 8 bytes on a 64-bit OS), whereas you really want the number of bytes required to store what the pointer points to (an int, i.e. 4 bytes on most OSes). Because typically sizeof(int *)>=sizeof(int), this probably wouldn't have caused a problem, but it's something to be aware of. I've corrected this in the code above.

Here are some useful questions on pointers-to-pointers:

How do pointer to pointers work in C?

Uses for multiple levels of pointer dereferences?

Assigning a variable to a specific memory location

In common general-purpose computers, you cannot assign addresses for objects. The addresses are managed for you by other software, and trying to set your own address for an object may interfere with other uses of that memory, may result in a trap if the memory is not mapped in the address space of your process, and may have other adverse consequences.

Assuming this code is for a hypothetical computer in a classroom study, and the computer and the C implementation have typical properties, such as eight-bit char (and that char is unsigned), then:

  • char *C,A=0,B=0x20 defines C to be a pointer to char. (This line should have a semicolon to mark its end.)
  • C=0x55 attempts to set C to point to the address 0x55. This is not the correct way to do this because C is a pointer, meaning its values are addresses, and 0x55 is a plain integer, not an address. The compiler should warn about this statement. A correct way to do this is to use a cast to convert the integer to a pointer: C = (char *) 0x55;.
  • After this, the loop starting with while(B) will execute as long as B is non-zero. Inside the loop, B=B+ *C; adds the contents of the memory C points to to B. Since you tell us the memory in that area is filled with 0x20, it adds 0x20 to B.
  • If we assume the computer and the C implementation have typical properties, this will continue with B being assigned the value 0x40, 0x60, 0x80, 0xa0, 0xc0, and 0xe0. Then the next addition will produce 0x100. 0x100 exceeds the eight bits in the char B, and it will wrap, putting 0x00 in B.
  • After B is set to 0x00, the while(B) loop will end.
  • So the loop will execute 7 times (once to set B to 0x40, then to 0x60, and so on, until it sets B to 0x00).
  • In each iteration, A is incremented by one. Since A starts at 0 and is incremented 7 times, its final value is 7.

Note: The C++; statement changes the value of C, changing where it points. In general, this would affect what value is added in the statement B=B+ *C;. However, since each byte in that area is filled with the same value, there is no effect; *C is always 0x20 in this situation. If the bytes of memory had different values, then changing C with C++; would change what value is obtained for *C.



Related Topics



Leave a reply



Submit