Variable Pointer vs Memory Pointer - c

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.

Related

Why am I able to dereference and modify an `int * const` pointer? [duplicate]

This question already has answers here:
const usage with pointers in C
(6 answers)
Closed 7 years ago.
I know that a pointer have an address and content cell which holds an address.
So what happen to the pointer in the following code:
int a=5;
int* const ptr=&a;
*ptr=6;
The address ptr holds is not changed, so how can the value that ptr points to be changed?
int *const ptr = &a;
Here ptr is a constant pointer so you can't modify the location to which this pointer points to. But you can change the value stored in the location the pointer is pointing to.
So
*ptr = 6;
will modify the value of the variable a to 6.
What is not allowed is along with the existing code say you have
int b=5;
and you do
ptr = &b;
Then you are bound to get a error saying the constant pointer is being made to point to some other memory location.
If you go to a library and ask for a catalog then using the catalog find a book and then go and replace the book with a different one the catalog will still list the old book in it.
Similar thing happens in your code - the pointer (the reference itself) doesn't change, but what it points to does change.
If you meant to make the object that it points to be const then you need to declare it as such:
const int* ptr = &a;
or, to make both the object and the pointer const:
const int* const ptr = &a;
The value can change because what you are making constant is what the pointer points to, not what's inside of it.
Let me give you a way to think about it that is a good illustration but not meant to be literal. A pointer type could be viewed as an unsigned integer value (likely 32 or 64 bits in length, but that doesn't matter right now). In reality, all that's ever being stored into a pointer is an unsigned integer or Nil, which for our purposes we will call "zero".
When you define a pointer to be a constant in this way, you doing what this normally means; the content of this variable is constant. So the number that gets stuffed into this unsigned integer will not change.
However, when pointers are used (or dereferenced) they are special in that the value of the pointer is used to reference another memory location. That location is just another variable. Since your assignment does not change the actual pointer itself, it is completely valid. :)
Here the pointer ptr is of constant type. Constant pointer cannot change the address once it is loaded with an address.
In the third line *ptr=6; you are assigning the value to the address stored in the ptr pointer.ie.to a. So only the value of a changes to 6.
To change the address of ptr remove the keyword const and assign a address like ptr=&b
There is a 4-Byte area in memory, let's say at address 0x2000, this area is called "a"
With the instruction a=5the compiler (or better startup-code) fills this memory area with the 4-Byte integer 0x00000005 (which is 5 in decimal).
now another variable ptr is filled with the address of a: ptr = 0x2000.
The pointer contains the address of memory area a we say ptr points to a
*ptr means: the memory area ptrpoints to, in this case memory at 0x2000.
So finally *ptr=6 means that the integer/value 6 is filled into the memory area ptr points to.
Now the memory area at 0x2000 will contain 0x00000006 (decimal 6)
Edit
The modifier const in int* const ptrmeans that the actual value i.e. the adress in ptr will never change during the execution of the program, it will always point to / contain 0x2000.
This means that an assignment like
ptr = &b;
will fail with a compiler error message.
Here pointer is a constant type, Using that pointer you can only point the single memory address. now you can't point the another address using this pointer
int a,c;
int *const b=&a;
and when we are assign like this, it is through the error
b=&c;

Allocating a value to a pointer in c

I am trying to give a value to a pointer.
this code works fine
int i =5;
int *ptr ;
ptr = &i;
printf(" %d\n",*ptr);
but this code shows an error
int i =5;
int *ptr ;
*ptr = 5;
printf(" %d\n",*ptr);
can someone explain this to me?
int *ptr gets initialized to a random location, which possibly points to invalid memory, and you try to write 5 to that location.
When you declare int *ptr, you're creating a variable called ptr which can hold the address of an int. When you dereference it in *ptr = 5, you're saying "store 5 in the address that ptr points to" - but as ptr is uninitialised, where it points to is undefined. So you're invoking undefined behaviour.
An int * does not store an int, but just an address that points to one. There still has to be a real int at that address.
If you want to allocate an int that exists outside of the local scope, you can use malloc. A simple conversion of your example without error checking:
int *ptr = malloc(sizeof(int));
*ptr = 5;
printf(" %d\n",*ptr);
If you do use malloc, just remember to free the allocated memory when you're finished:
free(ptr);
The second version assigns 5 to the memory pointed to by ptr, but you haven't yet initialized ptr to point to a known location.
So it writes the value to the memory at whatever address happens to be in ptr, which is whatever was in memory where ptr was declared.
You can't deterrence a pointer that doesn't point to somewhere you own.
int* ptr;
That allocates space for the pointer, but it doesn't allocate space for the chunk the pointer points to.
Also, since it's not initialized, ptr has an indeterminate value. This means that not only does it likely point to something you don't own, it also would be rather difficult to check if it's a valid pointer. It's usually a good idea to initialize pointers to either NULL (or nullptr if available) or an actual location (like you did in the first example).

Difference between pointer and array in terms of memory [duplicate]

This question already has answers here:
Pointers - Difference between Array and Pointer
(2 answers)
Closed 9 years ago.
char* pointer;
char array[10];
I know that the memory of second one is already allocated in the buffer. But, I don't know how exactly pointer works in terms of memory allocation. How much space does pointer initially takes before it is allocated by the programmer with malloc or calloc? Additionally, if I initialize it like this
char* pointer;
pointer = "Hello World!";
If the memory isn't allocated before it's initialized with some random string size, how is this being initialized? Wouldn't there be any error involved?
I was just programming with pointers and arrays mechanically w/o really knowing how it works inside the computer. And, I thought I should understand this perfectly for better programming practice.
Pointer is just to store address of one variable. i.e, if you say char* it stores address of one character. like int i=9; means memory of sizeof(int) is reserved and labled as "i" inyour program. Like wise char* c; means memory of size(char*) is reserved and labled as "c"; in c="hello"; "h","e","l","l","o" got seperate "continous" memory allocated. and pointer c points to first char "H".
consider in memory HELLO is store before string "India".
"HELLOINDIA."
for char *c="HELLO"; c[5] returns I.
for char c[5]="HELLO"; c[5] is array out of bound error.
char array[10] ,
It will reserve memory of 10 bytes on stack frame of function in which you have declared it.
Whereas in char *ptr = "hello" ptr will get 4 bytes memory on stack in 32 bit O.S,also "hello" is string literal which will get stored on non-bss part of your executable,and ptr is pointing to it from stack frame.
This declaration:
char *pointer;
reserves sizeof(char *) bytes for the pointer value. No other memory is allocated.
This declaration:
char array[10];
reserves 10 bytes for the array.
In this case:
char *pointer;
pointer = "Hello World!";
You still have a single pointer (sizeof(char *) in size) that points to a string literal somewhere in memory - no other allocations are taking place. Storage for the string literal is worked out by your toolchain at compile time.
Pointers and arrays are completely different things. Any similarity and confusion between the two is an artifact of the C language.
A pointer is a variable which holds the location of another variable. An array (in C) is an aggregate of values of identical type, consecutively allocated in memory.
Arrays are accessed via arithmetic upon a pointer to the base element, [0]. If an expression which refers to an array is evaluated, the value which emerges is a pointer to element [0].
int array[10];
int *p = array; /* array expression yields pointer to array[0] */
int *q = &array[0]; /* q also points to same place as p */
The array notation in C is a sham which actually works with pointers. The syntax E1[E2] means the same thing as *(E1 + E2) (assuming that E1 and E2 are sufficiently parenthesized that we don't have to be distracted by associativity and precedence.) When we take the address of an element via &E1[E2], this is the same as &*(E1 + E2). The address-of and dereference "cancel out" leaving E1 + E2. Therefore, these are also equivalent:
int *r = array + 3;
int *q = &array[3];
Because array[i] and pointer[i] are both valid syntax, people in the newbie stage (mistaking syntax to be semantics) conclude that arrays and pointers are somehow the same thing.
Spend some time programming in an assembly language. In assembly language, you might define some storage like this:
A: DFS 42 ;; define 42 words, labelled as A.
Then use it like this:
MOV R13, A ;; address of A storage is moved into R13
MOV R1, [R13 + 3] ;; load fourth word, A[3]
R13 points to the storage. That doesn't mean A is a pointer. A is the name of the storage. Of course to use the storage, we need its effective address and so a reference to A resolves to that. When the code is assembled and linked, that MOV instruction will end up loading some numeric address into R13.
C is just a higher level assembly language. Arrays are like named storage which resolves to its effective address (being a pointer data type).
Arrays do not always resolve to their effective address. sizeof a calculates the size of an array a in bytes, whereas sizeof p calculates the size of the pointer data type p.
Another difference is that the name of an array cannot be made to refer to any place other than that array, whereas we can assign values to pointers:
array++; /* invalid */
array = &array[0]; /* invalid */
p = &array2[0]; /* valid */
p++; /* valid: point to the next element in array2 */
A pointer takes up whatever space is required to describe a memory location. In general (but not always), the size of a pointer is the same as the bit-size of the processor/OS/program-mode (e. g. 8 bytes for a 64-bit program on a 64-bit OS, 4 bytes on a 32-bit program, etc.). You can find this out using
sizeof (void *)
In the case of
char* pointer;
pointer = "Hello World!";
You'll have one pointer allocated in R/W memory, plus the space for the string (13 bytes, including the trailing null byte) in R/O memory, perhaps more if the next object in memory is aligned on better than a byte boundary). Note that the same R/O space would be allocated for
printf("Hello World!");
so that actually has nothing to do with the pointer. In fact, most optimizing compilers would notice that the two strings are exactly the same and only allocate it once in R/O memory.
I don't know how exactly pointer works in terms of memory allocation. How much space does pointer initially takes before it is allocated by the programmer with malloc or calloc?
pointer itself is just a data type, like int, char...etc.
it point to a memory address (or NULL).
it can be malloc, become a pointer point to a block of memory you ask.
you very likely mistaken that pointer = malloc, it's not.
when you define a pointer in c, e.g. char *c; or int *i it will reserve a memory equal to sizeof(char *) and sizeof(int *) respectively.
But the actual memory reserved depends on your system/OS, if it is 64-bit it will reserve 8 bytes, if it is 32-bit it reserves 4 bytes.
In case of declaring char *c = "Hello world";
the string "Hello world" can be stored any where in memory but here c points to first character of the string that is 'H'.

Very Basic C Question

Can someone check my understanding and correct me if i am wrong?
int p = 5; //create an int holding 5
int *ptr; //create a pointer that can point to an int
*ptr = &p; // not sure - does this mean that my pointer now points to memory address five, or that the memory address my pointer points at contains 5?
Sorry for the basic question - i have an assignmnet soon that requires the use of pointers and i really want to crack the basics before its set.
Almost there - change it to:
int p = 5; // create an int holding 5
int *ptr; // create a pointer that can point to an int
ptr = &p; // ptr now points at p
Your program is wrong. ptr is not initialized. Assigning to *ptr creates a memory violation most likely. You can't assign an int* (which &p is) to an int (which *ptr is).
Correct is:
ptr = &p;
Your ptr now points to the memory address that has 5 stored in it.
Also, I don't believe that code compiles. You probably want:
int p = 5; //create an int holding 5
int *ptr; //create a pointer that can point to an int
ptr = &p; // not sure - does this mean that my pointer now points to memory address five, or that the memory address my pointer points at contains 5?
A pointer is, basically, an address. Think about a pointer as an address label, and the value as the actual house. You can use the label to find the house, but the label isn't a house.
int *ptr; // declares a pointer to an int
So ptr is, essentially, a memory address. (It's possible that the C spec doesn't actually specify that it's an address, but bear with me).
int i = 5; // create a local int.
Declares an integer on the stack, and sets the value of it to 5. The address of i is somewhere in the stack space.
Let's look at one intermediate step before we go on. This probably wouldn't compile, and if it did, wouldn't actually do anything.
&i;
What this expression does is return the address of the variable i. It's the location of i in memory - the address of an integer.
And one last one...
*ptr;
Again, this probably wouldn't actually do anything, it's just an expression. But, what it does is dereference the pointer - it refers to the actual int located at the address contained in ptr.
Okay, so let's take a look at a few things that we can do.
ptr = i;
This doesn't do anything, at least anything we want to do. Probably won't compile, but I haven't checked it out. It doesn't do anything because it assigns an integer to the address of an integer. That's like sending a box through the post office to an address label - you actually want it to go to the house!
i = ptr;
Okay, this is the same thing as the last one, but in reverse. Following our analogy, this is trying to turn a house into a label!
*ptr = i;
Here we've dereferenced the pointer, and assigned the value of i to it. Dereferencing a pointer is essentially like using the label to drive to the house. Once we're there, we can do things to the actual house. This works because a dereferenced int pointer is an int, and an int is also an int.
ptr = &i;
This works too. &i basically makes a new label for the house 'i'. Since we have a pointer on both sides, we can assign one to the other. This is basically copying the address label for i to the address label called ptr.
*ptr = &i;
This doesn't make sense. We've started with two different things, and converted each into the other! Now we're trying to assign a label to a house, whereas before we were assigning a house to an address label.
You want
ptr = &p; // set ptr to point to the location holding p
Others already explained how to fix your code. For understanding, let me tell you what your wrong line does:
*ptr = &p;
*ptr dereferences the pointer, i.e., *ptr = ... assigns something into the memory slot to which ptr is pointing. Since ptr has not been initialized, it points to some unknown location in memory and *ptr = ... will probably fail with a Segmentation Fault or something similar.
Since ptr is a pointer to int, the right-hand side of *ptr = ... expects an int as well, but you pass to it the address of an int (&p), which results in a compiler warning.
I know this doesn't directly answer your immediate question (which others have already done), but I would recommend reading the section on pointers from the c-faq.
Lot's of good info.
int a=5;
declare the pointer type which is your storing
int *ptr;
assign address of variable to the pointer
ptr=&a;

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