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
definesC
to be a pointer tochar
. (This line should have a semicolon to mark its end.)C=0x55
attempts to setC
to point to the address0x55
. This is not the correct way to do this becauseC
is a pointer, meaning its values are addresses, and0x55
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 asB
is non-zero. Inside the loop,B=B+ *C;
adds the contents of the memoryC
points to toB
. Since you tell us the memory in that area is filled with0x20
, it adds0x20
toB
. - If we assume the computer and the C implementation have typical properties, this will continue with
B
being assigned the value0x40
,0x60
,0x80
,0xa0
,0xc0
, and0xe0
. Then the next addition will produce0x100
.0x100
exceeds the eight bits in thechar
B
, and it will wrap, putting0x00
inB
. - After
B
is set to0x00
, thewhile(B)
loop will end. - So the loop will execute 7 times (once to set B to
0x40
, then to0x60
, and so on, until it setsB
to0x00
). - In each iteration,
A
is incremented by one. SinceA
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
Why Are the Return Values of These Doubles -1.#Ind
How to Omit the Double-Braces for Std::Array in C++14
Undefined Reference to Mempcy@Glibc_2.14 When Compiling on Linux
In Which Access Control Context Are Concepts Evaluated
Ordering of Using Namespace Std; and Includes
Uniform Initialization Fails to Copy When Object Has No Data Members
How to Include Data Object Files (Images, etc.) in Program and Access the Symbols
How to Parse CSV Using Boost::Spirit
Dependent Name Resolution & Namespace Std/Standard Library
C++ Regex for Overlapping Matches
C++: Where Does the Ofstream Class Save the Files To
Understanding the Difference Between F() and F(Void) in C and C++ Once and for All