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;
Related
See the two codes below!
int main() {
int a = 12;
int *p;
*p = a;
}
and the this code,
int main() {
int a = 12;
int *p;
p = &a;
}
In the first piece of code dereferenced the pointer as this *p = a, and in the second piece of code, the address of variabe a is set to the pointer variable.
My question is what is the difference between both pieces of codes?
In your first piece of code:
int main() {
int a = 12;
int *p;
*p = a;
}
you have a serious case of undefined behaviour because, what you are trying to do is assign the value of a to the int variable that p currently points to. However, p has not been assigned an 'address', so it will have an arbitrary - and invalid - value! Some compilers may initialise p to zero (or NULL) but that is still an invalid address (on most systems).
Your second code snippet is 'sound' but, as it stands, doesn't actually achieve anything:
int main() {
int a = 12;
int *p;
p = &a;
}
Here, you are assigning a value (i.e. an address) to your pointer variable, p; in this case, p now points to the a variable (that is, it's value is the address of a).
So, if you appended code like this (to the end of your second snippet):
*p = 42;
and then printed out the value of a, you would see that its value has been changed from the initially-given 12 to 42.
Feel free to ask for further clarification and/or explanation.
Declaring *p and a is reserving some space in memory, for a pointer in first case, for what a is in the 2nd case (an int).
In these both cases, their values are not initialized if you don't put anything in it. That doesn't mean there is nothing in it, as that is not possible. It means their values are undetermined, kind of "random" ; the loader just put the code/data in memory when requested, and the space occupied by p, and the one occupied by a, are both whatever the memory had at the time of loading (could be also at time of compilation, but anyway, undetermined).
So you take a big risk in doing *p = a in the 1st case, since you ask the processeur to take the bytes "inside" a and store them wherever p points at. Could be within the bounds of your data segments, in the stack, somewhere it won't cause an immediate problem/crash, but the chances are, it's very likely that won't be ok!
This is why this issue is said to cause "Undefined Behavior" (UB).
When you initialized a pointer you can use *p to access at the value of pointer of the pointed variable and not the address of the pointed variable but it's not possible to affect value like that (with *p=a). Because you try to affect a value without adress of variable.
The second code is right use p = &a
The first one is bad:
int main() {
int a = 12;
int *p;
*p = a;
}
It means: put the value of variable a into location, pointed by pointer p. But what the p points? probably nothing (NULL) or any random address. In best case, it can make execution error like access violation or segmentation fault. In worst case, it can overwrite any existing value of totally unknown variable, resulting in problems, which are very hard to investigate.
The second one is OK.
int main() {
int a = 12;
int *p;
p = &a;
}
It means: get the pointer to (existing) variable a and assign it to pointer p. So, this will work OK.
What is the difference between dereferencing and assigning the address of a variable to pointer variable in C?
The latter is the premise for the first. They are separate steps to achieve the benefit of pointer dereferencing.
For the the explanation for where the difference between those are, we have to look what these guys are separately:
What is dereferencing the pointer?
First we need to look what a reference is. A reference is f.e. an identifier for an object. We could say "Variable a stands for the value of 12." - thus, a is a reference to the value of 12.
The identifier of an object is a reference for the value stored within.
The same goes for pointers. pointers are just like usual objects, they store a value inside, thus they refer to the stored values in them.
"Dereferencing" is when we "disable" this connection to the usual value within and use the identifier of p to access/refer to a different value than the value stored in p.
"Dereferencing a pointer" means simply, you use the pointer to access the value stored in another object, f.e. 12 in a instead through its own identifier of a.
To dereference the pointer the * dereference operator needs to precede the pointer variable, like *p.
What is assigning the address of a variable to a pointer?
We are achieving the things stated in "What is dereferencing a pointer?", by giving the pointer an address of another object as its value, in analogy like we assign a value to a usual variable.
But as opposed to usual object initializations/assignments, for this we need to use the & ampersand operator, preceding the variable, whose value the pointer shall point to and the * dereference operator, preceding the pointer, has to be omitted, like:
p = &a;
Therafter, The pointer "points" to the address the desired value is stored at.
Steps to dereferencing a pointer properly:
First thing to do is to declare a pointer, like:
int *p;
In this case, we declare a pointer variable of p which points to an object of type int.
Second step is to initialize the pointer with an address value of an object of type int:
int a = 12;
p = &a; //Here we assign the address of `a` to p, not the value of 12.
Note: If you want the address value of an object, like a usual variable, you need to use the unary operator of &, preceding the object.
If you have done these steps, you are finally be able to access the value of the object the pointer points to, by using the *operator, preceding the pointer object:
*p = a;
My question is what is the difference between both pieces of codes?
The difference is simply as that, that the first piece of code:
int main() {
int a = 12;
int *p;
*p = a;
}
is invalid for addressing an object by dereferencing a pointer. You cannot assign a value to the pointer´s dereference, if there isn´t made one reference before to which the pointer do refer to.
Thus, your assumption of:
In the first piece of code I dereferenced the pointer as this *p = a...
is incorrect.
You do not be able to dereference the pointer at all in the proper way with *p = a in this case, because the pointer p doesn´t has any reference, to which you are be able to dereference the pointer correctly to.
In fact, you are assigning the value of a with the statement of *p = a somewhere into the Nirwana of your memory.
Normally, the compiler shall never pass this through without an error.
If he does and you later want to use the value, which you think you´d assigned properly by using the pointer, like printf("%d",*p) you should get a Segmentation fault (core dumped).
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;
What is the actual value of pointer:
char *ptr;
And it's pointing to a memory address, correct?
Not yet; it's uninitialized.
What you're asking is like asking what number int i; refers to.
I will try to explain in a simple way, (sorry if my English is not god enough i am learning)
Let say you have an array of characters:
char a[5];
Then you want to create a pointer to the address of the first element:
char *p = &a[0];
Now since the name of an array is a synonym for the location of the
initial element you can rewrite to the following statement:
char *p = a;
Now here is where magic takes place, as the previous character pointer points to the address of the first element you can do stuffs like the following:
instead of getting the 'i'-th element from a[i], you can move the pointer 'i' places to reference the address of the value contained in the 'i'-th position and then get it's value:
char value = *(a + i);
Font(The C programming language 2nd Edition, Chapter 5)
char *ptr;
It is not pointing any memory address until it is initialized;
But you can use it to point an address.
Suppose,
int i=0;
i has an address in memory. if it become 0xFFFF0 then when you write
ptr=&i;
then your pointer points to address 0xFFFF0 .
now suppose,
int array[5]={0}; is an array.
then if you write-
ptr=array;
then ptr points to the starting address of array because array name is an address.
Yes, it is pointing to the address of the variable.
The variable might be on the stack if the variable is declared inside a function, or at the top of RAM if declared at the top level.
As the other answers point out, you haven't made it point to anything yet, so dereferencing the pointer will likely result in a segmentation fault.
You need to do something like
char ch;
char *ptr = &ch;
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).
As I know, when a pointer is passed into a function, it becomes merely a copy of the real pointer. Now, I want the real pointer to be changed without having to return a pointer from a function. For example:
int *ptr;
void allocateMemory(int *pointer)
{
pointer = malloc(sizeof(int));
}
allocateMemory(ptr);
Another thing, which is, how can I allocate memory to 2 or more dimensional arrays? Not by subscript, but by pointer arithmetic. Is this:
int array[2][3];
array[2][1] = 10;
the same as:
int **array;
*(*(array+2)+1) = 10
Also, why do I have to pass in the memory address of a pointer to a function, not the actual pointer itself. For example:
int *a;
why not:
allocateMemory(*a)
but
allocateMemory(a)
I know I always have to do this, but I really don't understand why. Please explain to me.
The last thing is, in a pointer like this:
int *a;
Is a the address of the memory containing the actual value, or the memory address of the pointer? I always think a is the memory address of the actual value it is pointing, but I am not sure about this. By the way, when printing such pointer like this:
printf("Is this address of integer it is pointing to?%p\n",a);
printf("Is this address of the pointer itself?%p\n",&a);
I'll try to tackle these one at a time:
Now, I want the real pointer to be changed without having to return a pointer from a function.
You need to use one more layer of indirection:
int *ptr;
void allocateMemory(int **pointer)
{
*pointer = malloc(sizeof(int));
}
allocateMemory(&ptr);
Here is a good explanation from the comp.lang.c FAQ.
Another thing, which is, how can I allocate memory to 2 or more dimensional arrays?
One allocation for the first dimension, and then a loop of allocations for the other dimension:
int **x = malloc(sizeof(int *) * 2);
for (i = 0; i < 2; i++)
x[i] = malloc(sizeof(int) * 3);
Again, here is link to this exact question from the comp.lang.c FAQ.
Is this:
int array[2][3];
array[2][1] = 10;
the same as:
int **array;
*(*(array+2)+1) = 10
ABSOLUTELY NOT. Pointers and arrays are different. You can sometimes use them interchangeably, however. Check out these questions from the comp.lang.c FAQ.
Also, why do I have to pass in the memory address of a pointer to a function, not the actual pointer itself?
why not:
allocateMemory(*a)
It's two things - C doesn't have pass-by-reference, except where you implement it yourself by passing pointers, and in this case also because a isn't initialized yet - if you were to dereference it, you would cause undefined behaviour. This problem is a similar case to this one, found in the comp.lang.c FAQ.
int *a;
Is a the address of the memory containing the actual value, or the memory address of the pointer?
That question doesn't really make sense to me, but I'll try to explain. a (when correctly initialized - your example here is not) is an address (the pointer itself). *a is the object being pointed to - in this case that would be an int.
By the way, when printing such pointer like this:
printf("Is this address of integer it is pointing to?%p\n",a);
printf("Is this address of the pointer itself?%p\n",&a);
Correct in both cases.
To answer your first question, you need to pass a pointer to a pointer. (int**)
To answer your second question, you can use that syntax to access a location in an existing array.
However, a nested array (int[][]) is not the same as a pointer to a pointer (int**)
To answer your third question:
Writing a passes the value of the variable a, which is a memory address.
Writing *a passes the value pointed to by the variable, which is an actual value, not a memory address.
If the function takes a pointer, that means it wants an address, not a value.
Therefore, you need to pass a, not *a.
Had a been a pointer to a pointer (int**), you would pass *a, not **a.
Your first question:
you could pass a pointer's address:
void allocateMemory(int **pointer) {
*pointer = malloc(sizeof(int));
}
int *ptr;
allocateMemory(&ptr);
or you can return a pointer value:
int *allocateMemory() {
return malloc(sizeof(int));
}
int *ptr = mallocateMemory();
I think you're a little confused about what a pointer actually is.
A pointer is just variable whose value represents an address in memory. So when we say that int *p is pointer to an integer, that just means p is a variable that holds a number that is the memory address of an int.
If you want a function to allocate a buffer of integers and change the value in the variable p, that function needs to know where in memory p is stored. So you have to give it a pointer to p (i.e., the memory address of p), which itself is a pointer to an integer, so what the function needs is a pointer to a pointer to an integer (i.e., a memory address where the function should store a number, which in turn is the memory address of the integers the function allocated), so
void allocateIntBuffer(int **pp)
{
// by doing "*pp = whatever" you're telling the compiler to store
// "whatever" not in the pp variable but in the memory address that
// the pp variable is holding.
*pp = malloc(...);
}
// call it like
int *p;
allocateIntBuffer(&p);
I think the key to your questions is to understand that there is nothing special about pointer variables. A pointer is a variable like any other, only that the value stored in that variable is used to represent a position in memory.
Note that returning a pointer or forcing the caller to move the pointer in an out of a void * temp variable is the only way you can make use of the void * type to allow your function to work with different pointer types. char **, int **, etc. are not convertible to void **. As such, I would advise against what you're trying to do, and instead use the return value for functions that need to update a pointer, unless your function by design only works with a specific type. In particular, simple malloc wrappers that try to change the interface to pass pointer-to-pointer types are inherently broken.