Strange pointers initialization - c

Today I had an exam on ponters in C, and there was some questions about double pointers where the following syntax was used
*pointer = &variable;
I don't know if I have done correctly, but can someone explain where will pointer point to and how will the value in variable change? At first I thought it will cause sntax error, but there was no such answer in a test. Thanks in advance

// two int variables.
int var1;
int var2;
// int pointer pointing to var1
int *ptr = &var1;
// pointer to int pointer..pointing to ptr
int **ptr_to_ptr = &ptr;
// now lets make the pointer pointed to by ptr_to_ptr
// point to var2
*ptr_to_ptr = &var2;
// or alternatively you can do:
// ptr = &var2;

Here's an example on how you could use it:
int foo = 123;
int **bar = malloc(sizeof(int *));
*bar = &foo;
Now bar is a pointer to a pointer to foo. Doesn't make much sense though.

pointer is a pointer to a pointer.
Eg,
int var1=42;
int* intptr;
int** ptr2intPtr;
ptr2intptr = &intptr;
//Syntax in question.
*ptr2intptr = &var1;
//Just like *intptr is same as var1, *ptr2intptr is same as intptr
//so the above line will be equivalent to intptr = &var1
//All the three are the same
printf("%d",**ptr2intptr);
printf("%d",*intptr);
printf("%d",var1);

If the pointer is initialized this way:
int *pointer;
int variable = 10;
pointer = malloc(sizeof(int));
*pointer = &variable;
*pointer = &variable means the address of variable is set as value of the pointee. Since *pointer is dereferencing so you are basically storing a value not setting a reference.

Related

Pointer initialization: address or value

I have a question regarding pointer initialization in C.
I understand that *ptr will give the value of that pointer is pointing to.
ptr will give you the address.
Now I got following syntax:
int *ptr = (int *) malloc(sizeof(*ptr));
Why is *ptr being initialized with an address of the Heap and not a value? malloc() returns an address right?
Shouldn't it be:
int *ptr;
ptr = malloc(...);
With *ptr, * is acting as the dereferencing operator.
With int *ptr, * is acting as part of the type declaration for ptr.
So the two things are entirely different, even though * is used. (Multiplication and comment blocks are further uses of * in C).
In that line, int * is the type.
int *ptr = (int *) malloc(sizeof(*ptr));
Is just this compressed into one line:
int *ptr;
ptr = (int *) malloc(sizeof(*ptr));
Actually , this:
int *ptr = (int *) malloc(sizeof(*ptr));
Is just short syntax for this:
int *ptr;
ptr = malloc(...);
The * is used for defining a type pointer and not to dereference the pointer .
Both snippets above do the same thing.
In the first case, the * before ptr is not the derefernece operator but is part of the definition of the type. So you actually are assigning a value to (initializing, actually) ptr, not *ptr.
The difference between
int *ptr = (int *) malloc(sizeof(*ptr));
and
int *ptr;
ptr = malloc(...);
is basically the same as the difference between
int i = 5;
and
int i;
i = 5;
The first variant defines and initializes a variable in one go. The second variant defines the variable but leave it uninitialized, and then assign a value to it.

usage of double pointers as arguments

Please find the code snippet as shown below:
#include <stdio.h>
int My_func(int **);
int main()
{
int a =5;
int *p = &a;
My_Func(&p);
printf("The val of *p is %d\n,*p);
}
void My_Func(int **p)
{
int val = 100;
int *Ptr = &val;
*p = Ptr;
}
How does by using a double pointer as a argument in my_Func function and making change of value reflects the same in the main function but if we use a single pointer in My_Func does not change the value in main?Please do explain me with examples if possible
Advanced thanks
Maddy
int **p is a pointer to a pointer-to-int. My_Func(int **p) works by changing the value of integer that the pointer-to-int points to i.e. int a.
Without changing the implementation, the function will not work with a pointer-to-int parameter int *p as there is a second level of indirection. In addition, you're setting the value to a local variable that is created on the stack. When the function is completed the memory used for the variable will be reclaimed, therefore making the value of a invalid.
void My_Func(int **p)
{
int val = 100; // Local variable.
int *Ptr = &val; // This isn't needed.
*p = Ptr;
} // val dissapears.
Remove the second level of indirection and copy val by value instead of pointing to it:
#include <stdio.h>
void My_Func(int *p)
{
int val = 100;
*p = val;
}
int main(void)
{
int a = 5;
My_Func(&a);
printf("The val of a is %d\n", a);
return 0;
}
In short, in C when you pass something as a parameter, a copy will be passed to the function. Changing the copy doesn't affect the original value.
However, if the value is a pointer, what it points to can be changed. In this case, if you want to affect the pointer, you need to pass a pointer to it down to the function.
Use it in the function declaration:
void func(int *p)
{
int val =100;
int *temp=&val;
p=temp;
}
p starts pointing to another address i.e. address of val. So it will print the value 100.
Important note: Try it in your downloaded compiler (always in case of pointers) not in the online compiler. The online compiler doesn´t keep track of lost addresses in stack.
You are assigning the address of local variable, which will soon disappear when My_Func returns. You can use following in your code. However you can do the same thing just by using single pointer, double pointer is not required in this example.
void My_Func(int **p)
{
int val = 100;
int *Ptr = &val;
**p = *Ptr;
}

Does ptr = &a and *ptr = a mean the same?

In the book it explains:
ptr = &a /* set ptr to point to a */
*ptr = a /* '*' on left:set what ptr points to */
They seem the same to me, aren't they?
No. The first one changes the pointer (it now points at a). The second one changes the thing that the pointer is pointing at.
Consider:
int a = 5;
int b = 6;
int *ptr = &b;
if (first_version) {
ptr = &a;
// The value of a and b haven't changed.
// ptr now points at a instead of b
}
else {
*ptr = a;
// The value of b is now 5
// ptr still points at b
}
Well, no. But to explain the similar behaviour, Adding to Oli Charlesworth's answer:
Consider:
int a = 5;
int* ptr = new int;
if(first_version) {
ptr = &a;
//ptr points to 5 (using a accesses the same memory location)
} else {
*ptr = a;
//ptr points to 5 at a different memory location
//if you change a now, *ptr does not change
}
edit: sorry for using new (c++ not c) but the pointer thing does not change.
No, in ptr = &a you are storing the address of variable 'a' in variable 'ptr'
i.e., something like ptr=0xef1f23.
in *ptr = a you are storing the value of variable 'a' in pointer variable '*ptr'
i.e., something like *ptr=5.
Both are not same.
If u modify the value of a = 10. Then print again *ptr. It will print only 5. not 10.
*ptr = a; //Just copies the value of a to the location where ptr is pointing.
ptr = &a; //Making the ptr to point the a
*ptr=&a C++ compiler will genrate error becoz u r going to assign addres to adres
ptr=&a,this is true here ptr working like variable and &a is a addres of a which contain some value
check and try
int *ptr,a=10;
ptr=&a;output=10;
*ptr=&a signifies that our pointer is pointing towards address of the variable a
while
*ptr=a signifies that our pointer is pointing towards value a
*ptr = &a is not technically correct.
int *ptr = &a; is correct ..... Way (i)
(or)
int *ptr;
ptr = &a; is correct ..........Way (ii)
Here *ptr is a pointer to integer datatype.
int *ptr;
*ptr = a; This means ptr becomes a NULL pointer [i.e. it does not point to any memory location]. *ptr holds the value of a.

How to set pointers throught functions?

I have a question about C pointers. Because I was wondering if I could set pointers through functions.
I mean like this:
void initptr(int **ptr)
{
ptr = (int *) malloc(sizeof(ptr));
}
int main()
{
int *ptr;
initptr(ptr);
}
Let me know.
Yes this is possible in C, you're just missing a dereference and address of operator in your sample
void initptr(int **ptr)
{
*ptr = (int *) malloc(sizeof(int*));
}
int main()
{
int *ptr;
initptr(&ptr);
}
The deference operator in *ptr = ... converts the type of ptr from int** to int* thus making it compatible with the assignment. Note: the casting of malloc is uneedded here.
The address of operator in initptr(&ptr) reversely converts the type of ptr from int* to int** thus making it compatible with the argument slot.
EDIT
As B Mitch pointed out the malloc size needs updating as well. You appear to be allocating an int* value and hence want the size to be that of an int*.
I believe you want this:
*ptr = (int *) malloc(sizeof(**ptr));
yes, but you need dereference ptr in your function in order to change what it points to
e.g.
void initptr(int **ptr)
{
*ptr = ...
}
when you call the method write
initptr( &ptr );
ptr = (int *) malloc(sizeof(ptr));
You missed to dereference the pointer to pointer so that it can actually take a pointer.
*ptr = (int *) malloc(sizeof(ptr));
// * newly added.
And also call to initptr(ptr); is wrong.
void initptr(int **ptr) ;
The function has an pointer to pointer as an argument. So, the argument ptr needs to hold the address of a pointer. So, change it to -
int *ptr = NULL ; // Initialize pointers to NULL
initptr(&ptr); // Passing the pointers address

Changing the value of a pointed to integer in C

I want to declare a new integer in the heap,
int *intPtr = (int*) malloc(sizeof(int));
How do I change the value of the space in the heap, to which *intPtr points to?
Thanks
Dereference intPtr:
*intPtr = 0;
First of all, you don't need to cast the result of malloc. malloc returns a void* and the void* is casted implicitly to any pointer (int*, char*, ...).
So :
int *intPtr = malloc(sizeof(int));
You can also write :
int *intPtr = malloc(sizeof *intPtr);
If you want to change the value pointed by intPtr, just use the dereference operator '*' like :
*intPtr = <new_value>
where is your new integer value.

Resources