How can I assign a specific address to a variable? - c

How can I assign a specific address to an already stored variable?
#include <stdio.h>
void main()
{
int a = 10;
printf("%d\n%d\n", a, &a);
&a = 2300000;
}

No, there is no way by which you can assign an address to a variable. You can assign an arbitrary location ie., you can point to some address with a pointer like
int *ptr;
ptr = (int*)7000;
But changing or assigning a specific address is not possible.

You cannot change the address of a variable.The compiler does have facilities to assign an absolute memory address to a variable. Using pointer you can only point to some address. Like,
int *p;
p = (int*) 0x00010000;

The memory addresses that you see are not in fact actual physical memory addresses, but virtual addresses. every process receives its own virtual memory space and it is possible to have variables in a few processes with the same "address".
therefore changing the address cannot be done, and it is also meaningless to do so.
in unix, you can use posix_memalign to allocate an address that is aligned to a specific number, but it cannot be any address that you want, that is because C automatically aligns memory(for example padding of structs).
memory can only be aligned to a number that is a power of 2.

Related

What is the address of a pointer in C?

int main()
{
int *p;
printf("%p \n", &p);
printf("%p \n", p);
return 0;
}
By executing this code I am receiving the following output:
0x16b77f710
0x104683f4c
I expected to get the same memory address, because the &p id not referenced to any other variable.
Why i am getting two different memory address?
Thanks,
The pointer is a normal object having (in your case type of int *). It cant point to itself because the type of such pointer would have to be int **
*image stolen from internet.
A pointer is a variable like any other. It has an address, which is typically the address in memory where that variable sits.
Like any other variable, a pointer variable also has some data in it. For a pointer variable, that data is the address of some other variable, the variable at which the pointer points.
The address of a variable, and the contents of a variable, are two totally different things. They are almost never equal.
Try this program, in which I give your variable p something to point to:
int main()
{
int i = 5;
int *p = &i;
printf("p: %p, p's address: %p\n", p, &p);
printf("i: %d, i's address: %p\n", i, &i);
}
You should notice two things:
As in your first program, "p" and "p's address" will be different.
Whatever value you see for "p", it will be the same as "i's address".
The reason is that a pointer, when declared, does not point to itself by default. Simplified you can imagine it in such a way that a pointer occupies 2 memory cells. 1 memory cell has the virtual address where the pointer itself is located (&p in your case), the 2nd memory cell contains the virtual address where the pointer points to (p in your case).
Since memory cells retain their value when they are deallocated, the cell containing the destination address of your pointer still contains an obsolete value from another, already completed process.
You would have the same phenomenon if you declare a new integer variable and then print its value with printf, you will see that there will already be some number in the new variable that will appear completely random. This is also due to the fact that there is still an obsolete value in the corresponding memory cell.
Let assume there is random memory block for just understanding name it a. Now assume that p is pointing to that memory block.
&p returns the address of memory block where p is present.
p returns the address of memory block(&a) to the variable/memory block(a) which p is pointing.
So of course it will give different memory addresses.
I expected to get the same memory address, because the &p id not referenced to any other variable.
Pointer variables do not automatically point to themselves; if you don't explicitly initialize them, then their initial value will be indeterminate (or NULL, depending on how they are declared).
There's nothing magic about pointer variables - like any other scalar, they store some kind of value; it's just that in their case, that value is an address of another object.
If you really want p to store its own address, you'll have to do something like
p = (int *) &p;
The cast is necessary because the type of the expression &p is int **, and you can't assign a pointer value of one type to a variable of a different pointer type. But, pointers to different types are not guaranteed to have the same size, representation, or alignment. On modern commodity hardware like x86 you can probably count on int * and int ** having the same size and representation, just be aware that doesn't have to be the case everywhere.

Variable Pointer vs Memory Pointer

What is the difference between the two, a ptr pointing at a variable and a ptr pointing at memory? I know a pointer is a variable that holds the memory address of a variable. So... A ptr pointing at a variable holds the address of that variable whereas a ptr pointing at memory is directly pointing at memory? The first somehow still holds some information about the initial variable whereas the later only knows an address?
EDIT: I didn't mean for this question to cause so much controversy and I'm not entirely sure why it's getting downvoted. I'm just trying to understand pointers... After doing some reading on the linked 'duplicate' it is my understanding that a ptr pointing to a variable always references that variable, cannot be reassigned, and cannot point to other pointers, and share an address with the variable. Memory pointers can point to NULL, can be reassigned, can point to other pointers, and have their own memory address. Are these true for C or only C++
A pointer is a variable whose value is an address in memory. The pointer also knows the type of whatever it's pointing to (or else it's a void*).
Basically that's all there is to it. There is no fundamental distinction between a "pointer that points to a variable" and a "pointer that points to memory". Whatever the pointer points to is in memory in any case. Whether the pointer points to a char variable, or a double variable, or an object, it's always simply pointing to the memory location where that char/double/object is stored.
Here's the way I see it, and I'll go by example.
In C, a pointer variable can be declared as:
char* p;
Then you can reserve stack memory for your program via a char array like so:
char buffer[5000];
You can then make the pointer reference this memory block like so:
p=buffer;
Variables by default point to their own addresses in stack memory for fast access. If you want to assign a pointer to memory from the heap, you can use calloc() or malloc(). For example, this code:
char* m;
m=malloc(5000);
... allocates 5000 bytes of memory from the heap (aka extended memory). then when you make reference to that pointer, you're actually reading to and writing from RAM.
This prints the letter "A" to the same static memory location twice then reads it back:
char block[10];
char* p=block;
block[0]='A'; //write to 1st position of block memory
*p='A'; //write same value to 1st position of block memory again
char *r;
r=p;
printf("%c",*r);
And now the same program but this time using just memory from the heap:
char* block;
block=malloc(10);
char* p=block;
block[0]='A'; //write to 1st position of block memory
*p='A'; //write same value to 1st position of block memory again
char *r;
r=p;
printf("%c",*r);
free(block);
please note that i am still learning and some information might be wrong
ok for example lets make
int i = 5;
int *ptr = &i;
lets say memory address for those are
i = 0x0001
ptr =0x0002
in those memory address are
0x0001 = 0101 // this is 5 for binary
0x0002 = 0x0001 //this is the address of 'i'
so when ptr is called in these kind of ways u get these values
ptr = 0x0001 // the address stored in ptr
*ptr = 0101 // the * means whatever is at the address stored in ptr
if i had wrote like this
int i = 5;
int *ptr = *i;
then ptr will have whatever is at 'i'
i = 0x0001
ptr = 0101
so if i call ptr again in these ways
ptr = 0101
*ptr // this will not work cus 0101 is not a memory address
edit
Also on your edit u said "that a ptr pointing to a variable always references that variable, cannot be reassigned, and cannot point to other pointers, and share an address with the variable."
This is not true for C, a pointer can be reassigned whenever u want and can point to other pointers
Unless it was made as a
const int *ptr = &i;
Then the pointer can not be changed later
Also u said "memory pointers can point to NULL, can be reassigned, can point to other pointers, and have their own memory address"
This is true as I said above but there are no such thing as a memory pointer and a variable pointer, there is only pointer that can hold a memory address.

Assigning/Casting integers to pointers

#include<stdio.h>
#define int int*
main(){
int *p,q;
p=(int *)5;
q=10;
printf("%d",q+p);
}
my question is that in line p=(int *)5, and q=10 how it's working internally exactly because p and q are both pointer types, how is it possible that we can assign an integer value to pointer variable q?. One more thing how this type casting p=(int*)5 working here ?
By using this formula we can answer
new address = old address+number * sizeof data type to which pointer is pointing
#define int int* will replace int *p, q as int* *p, q. So Here p is double pointer to int and q is of type int.
For example consider the below program of your same logic in char
#include<stdio.h>
#define char char*
main()
{
char *p,q;
printf("%d, %d\n", sizeof(p), sizeof(q));
}
Output is
4, 1
p=(int *)5; - This statement also will be replaced like p=(int* *)5; by preporcessor. So its not throwing any warning.
so now printf("%d",q+p); will gives you 45 in case of 32 bit machine or 85 incase of 64 bit machine.
Pointers as indeed all data in a computer are, regardless of their logical meaning, physically implemented as numbers.
In the case of pointers, typically the numbers are virtual addresses; as such, when you manually assign a value to a pointer, you are setting a virtual address.
As it happens virtual addresses typically range from 0 to the address bus width of the CPU, so you get away with it - except of course that address has not been allocated and acccess it will cause an exception.
Sometimes however (typiclally embedded systems without virtual memory) the addresses are physical, not virtual, and some hardware devices (clocks, registers, etc) have known physical addresses, which are hand assigned to pointers and then the pointers are read from / written to.
p=(int *)5;
Variable p points on address 00000005. If to try to change value to this address, It can lead to damage of other data and an unpredictable program runtime.
For example
**p=10
causes exception
Unhandled exception : Access violation writing location 0x00000005.
Try printf("%p",p) before next operation to see initial address of poiner p.
printf("%d",q+p);
Here magic of address arithmetics starts.. You can add address of pointer q to another pointer. So the pointer moves on new position in address space. Try this:
p = p+ q
printf("%p",p);

How many consecutive nested pointer (pointer to pointer) can i have in one order? Is there a limit of doing references?

The follow program declares a pointer then again a new pointer to hold address of previous pointer variable.. How much can I use nested pointer variable to hold memory address
is there any limit?
#include <stdio.h>
#include <conio.h>
void main()
{
int x=2,y=5;
int *ptr;
int **sptr;
int ***ssptr;
ptr = &x; // address of x
*ptr = 0;
sptr = &ptr;
ssptr = & sptr;
printf(" address is ip = %u %u %u",ptr,sptr,ssptr);
_getch();
}
There is no limit. A pointer is a chunk of memory (typically one word) whose contents are an address. A pointer to a pointer is also a word whose contents are an address, but it just so happens that the contents at that address is another address. There is nothing particularly special about a pointer to a pointer (to a pointer to a pointer... etc., ad nauseum).
There is no limit. You can even make a pointer that points at itself, which is infinitely recursive:
void *p = &p;
As far as I know, there shouldn't be any limit except for system memory restrictions (in theory). This would depend on the compiler used though.
There is not a limit in the language itself. The purpose of a pointer variable is to store an address. It is possible to store a pointer which points to an address, which points to an address, ..., which points to an address.
However, the more you use these types of nested pointers, the less understandable your code will be.
No there is no limit because they are all just pointers to something, and the thing they point to just happens to be another pointer.
Are you trying to do something practical?
Todd.
The only language I could find that suggests a limit is the following:
5.2.4.1 Translation limits
1 The implementation shall be able to translate and execute at least one program that
contains at least one instance of every one of the following limits:13)
...
— 12 pointer, array, and function declarators (in any combinations) modifying an
arithmetic, structure, union, or incomplete type in a declaration
...
— 4095 characters in a logical source line
...

Does a pointer also have any address or memory allocation?

If a pointer stores the address of a variable ... then from where do we get the pointer?
What I asked was that if we are using pointer directly, then there must be a location from where we get this pointer?
Yes, a declared pointer has its own location in memory.
In the example above, you have a variable, 'b', which stores the value "17".
int b = 17; /* the value of 'b' is stored at memory location 1462 */
When you create a pointer to that variable, the pointer is stored in its own memory location.
int *a;
a = &b; /* the pointer 'a' is stored at memory location 874 */
It is the compiler's job to know where to "get the pointer." When your source code refers to the pointer 'a', the compiler translates it into -> "whatever address value is stored in memory location 874".
Note: This diagram isn't technically correct since, in 32-bit systems, both pointers and int's use four bytes each.
Yes. Below I have an int and a pointer to an int and code to print out each one's memory address.
int a;
printf("address of a: %x", &a);
int* pA = &a;
printf("address of pA: %x", &pA);
Pointers, on 32bit systems, take up 4 bytes.
In C:
char *p = "Here I am";
p then stores the address where 'H' is stored. p is a variable. You can take a pointer to it:
char **pp = &p;
pp now stores the address of p. If you wanted to get the address of pp that would be &pp etc etc.
Look at this SO post for a better understanding of pointers.
What are the barriers to understanding pointers and what can be done to overcome them?
As far as your question goes, if I understand what you want, then, basically, when you declare a pointer, you specify an address or a numeric index that is assigned to each unit of memory in the system (typically a byte or a word). The system then provides an operation to retrieve the value stored in the memory at that address.
The compiler deals with translating the variables in our code into memory locations used in machine instructions.
The location of a pointer variable depends on where it is declared in the code, but programmers usually don't have to deal with that directly.
A variable declared inside a function lives on the stack or in a register, (unless it is declared static).
A variable declared at the top level lives in a section of memory at the top of the program.
A variable declared as part of a dynamically allocated struct or array lives on the heap.
The & operator returns the memory location of the variable, but unlike the * operator, it can't be repeated.
For example, ***i gets the value at the address **i, which is the value at address *i, which is the value stored in i, which the compiler figures out how to find.
But &&i won't compile. &i is a number, which is the memory location the compiler uses for the variable i. This number is not stored anywhere, so &&i makes no sense.
(Note that if &i is used in the source code, then the compiler can't store i in a register.)

Resources