Can I change the address of the pointer variable in C language? - c

For example, if there is a pointer variable int *a, int *b and each address value is 1000, 2000, can the address value of the pointer variable be swapped as if it were swapping the value of the common variable?
Note, I mean the address of the pointer. Not the value it contains.
As far as I know, the address value of the pointer variable is fixed and cannot be changed, is that right?

From comments:
A lot of people answered, but I think I asked the wrong question. I'm sorry, but my question is not about "change content of a pointer variable", but "change address of a pointer variable."
No, that's impossible for any variable. Not just pointers.

Can I change the address of the pointer variable in c language?
While the answer to your question would be yes for many other languages, including C++, kind of:
"While C++ doesn't directly support putting a variable at a given address, the same effect can be achieved by creating a reference to
that address:"...
...the answer for C is No. "A pointer has an address like other variables (which can't and needn't be changed)". (quote from 4th response in link.)
For C, the address of all variables (with the exception of those declared as register) are assigned at the time of declaration as a memory location provided by the operating system, and are immutable for the remainder of their life, no matter the scope in which they were created.
So, while the address pointed to by a pointer variable can be changed, the address of the variable itself, cannot.

Yes, you can:
void swapPointers(void **a, void **b) {
void *t = *a;
*a = *b;
*b = t;
}
void someOtherFunc() {
int *x = malloc(sizeof(int));
int *y = malloc(sizeof(int));
*x = 3;
*y = 5;
printf("x = %d y = %d\n", *x, *y);
swapPointers(&x, &y);
printf("x = %d y = %d\n", *x, *y);
}

Yes, you can swap the address the pointer points to.
int main()
{
int x = 5, y = 10;
int* p1 = &x;
int* p2 = &y;
printf("Address pointed by p1 is: %p\n", p1);
printf("Address pointed by p2 is: %p\n", p2);
//Here goes the swapping
int* p3 = p1;
p1 = p2;
p2 = p3;
printf("\n--After swap--\n");
printf("Address pointed by p1 is: %p\n", p1);
printf("Address pointed by p2 is: %p\n", p2);
}

I think you mean swapping addresses stored in pointers because you can not swap addresses of pointers as declared variables themselves.
To swap two objects in a function you have to pass them by reference. Otherwise the function will deal with copies of the values of passed directly to it objects.
In C passing by reference means passing an object indirectly through a pointer to it.
Pointers are the same objects.
So you can write the swap function the following way
void swap_ptr( int **a, int **b )
{
int *tmp = *a;
*a = *b;
*b = tmp;
}
And the function can be called like
int *a = /*...*/;
int *b = /*...*/;
//...
swap_ptr( &a, &b );

yes you can you just need to swap where each pointer point to.
declare a 3rd pointer then do the swap as follow.
//we have *a and *b
int *tmp;
tmp = a;
a = b;
b = tmp;

yes you can swap the address stored in two pointer using a temporary pointer variable. But if the pointer is declared as constant pointer for exapmle const int *ptr1; then it not possible because the address stored in ptr1 cannot be modified
#include <iostream>
using namespace std;
int main() {
int a=10;
int b=20;
int *ptr1;
int *ptr2;
ptr1=&a;
ptr2=&b;
cout<<ptr1<<" "<<ptr2<<"\n";
int *temp;
temp=ptr1;
ptr1=ptr2;
ptr2=temp;
cout<<ptr1<<" "<<ptr2;
return 0;
}
you can change the syntax to c because I thought that I was answering a question from c++ section

Related

Definition of double pointer

I m learning C programming and I have seen some code where folks use double pointers. I did some searching on stackoverflow from below but still have a teeny tiny question (Why use double pointer? or Why use pointers to pointers?)
In the code below, my question is I have not defined 'b' as **b. Now
when I try to do (*b) I`m getting a compile error. Isnt this *(*b) same as
*(address of c) because 'a' has address of 'c'.. Why do I need to define 'b' as **b to really get the value of 'c'?
#include <stdio.h>
int main()
{
int *a, *b, c;
c = 10;
a = &c;
b = &a;
printf("*a - %d\n *(*b): %d\n," , *a, *(*b));
return 0;
}
Help/explanation is really appreciated :)
EDIT : Thanks a lot guys for the explanation. Things are now clear :)
Here is a working code.
int main()
{
int *a, *b, c;
c=10;
a = &c;
b = a;
printf("*a - %d\n *(*b): %d\n,",*a, *(b));
return 0;
}
Pointers are aptly name: they "point" to locations in memory.
When you write *b, you tell the compiler that you are going to declaring a pointer of type integer so that it points to an integer.
When you use b = a, you tell the compiler that you are assigning the address of c to a as well. Actually, b is a pointer variable itself which is storing the address of an integer variable c. So, this way, you can assign the address of one variable to another pointer as well.
Now, Regarding your code,
int main()
{
int *a, **b, c; // just change it from *b to **b
c = 10;
a = &c;
b = &a;
printf("*a - %d\n *(*b): %d\n,",*a, *(*b));
return 0;
}
You need to specify the compiler that the pointer b is a pointer to a pointer variable by writing 2 *.When you write **b, you are telling the compiler that you are pointing to another pointer variable. Similarly, you can also have triple pointers and Quadrupled pointers as well.
Here is a link for your reference. http://www.c4learn.com/c-programming/c-double-pointer/
In your code, you have to do int **b; because:
a is a pointer-to-integer, since a = &c.
b is a pointer-to-(pointer-to-integer), since you wrote b = &a.
You can access the value of c using *b.. change your code littlebit..
#include <stdio.h>
int main()
{
int *a, *b, c;
c = 10;
a = &c;
b = a;
printf("*a :%d\n *b: %d\n,",*a, *b);
return 0;
}
*b,*a
defines that a and b are two pointer variable..
a=&c;
Assign the address of the variable c in pointer a.. & stand for address of operator.
b=a;
Copy the contains of a in b.. Now b also contain the address of c..
Print *a and *b.. *a and *b means contain of a and b. So *a and *b will print value of c..
You can also use **b.. **b means b is a pointer which stores address of another pointer variable..
In that case the code will be,
#include <stdio.h>
int main()
{
int *a, *b, c;
c = 10;
a = &c;
b = &a;
printf("*a :%d\n *b: %d\n,",*a, *(*b));
return 0;
}
a contains address of c and b contains address of a.. So, *a will print value of c..
As b is a double pointer we need *(*b) to access the contain of b.. *(*b) will also print the value of c..

What is the difference between `*a =` and `= *a`?

In following function,
void swap(int * a, int * b) {
int t;
t = *a; // = *a
*a = *b; // a* =
*b = t;
}
What is the difference between = *a and *a =?
I've heard that the * operator in = *a is a de-referencing(or in-directing) operator which fetches(?) that value from the pointer.
Then, what is the actual meaning of *a =?
Yesterday, the day I asked this question, I explained about pointers to my colleague whose major field has nothing to do with pointers.
I quickly typed a source code like this.
#include <stdio.h>
void swap1(int a , int b) {
int t = a;
a = b;
b = t;
}
void swap2(int * a, int * b) {
int t = *a;
*a = *b;
*b = t;
}
int main(int argc, char * argv[]) {
int a = 10;
int b = 20;
swap1(a, b);
swap2(&a, &b);
}
I was even proud of myself for remembering things imprinted on my brain in 1996. (I've been with Java for almost 20 years.)
I used a bunch of printfs with %ds and %ps to show her what was happening.
Then I made a terrible mistake. I declared.
포인터 변수 앞에 별을 붙이면 값을 가져온다는 뜻이에요.
When you attach a STAR in front of a pointer variable, that means you fetches(retrieves) the value.
Well that could be applied to following statement.
int t = *a;
Which simply can be said,
int t = 10;
The big problem I faced came from the second statement.
*a = *b; // 10 = 20?
The root evil is that I didn't try to explain about the dereference operator or I didn't ask to myself of being aware of the meaning of a 별(star).
Here is what people would say.
for = *a,
the actual value at the address denoted by a is assigned to the left side.
for *a =
the value of the right side is stored in the address denoted by a.
That's what I'm confusing of. And that's why I should re-think about the meaning of `de-referencing'.
Thanks for answers.
Oh I think this problem is going deeper to the concepts of lvalues and rvalues.
The first one is reading from the memory a is pointing to. The second one is writing to that memory.
This is no different from x = and = x except that you do not access the variable directly but the object it is pointing to.
Here:
t = *a;
the pointer a is dereferenced and this value is assigned to t whereas here:
*a = *b;
both b and a are dereferenced and the value of *b is stored in the address a.
I've heard that the * operator in = *a is a de-referencing(or in-directing) operator which fetches(?)
In fact fetch happens when you dereference a pointer with operator * alone. Hence assignment = operator doesn't involve in dereferencing perhaps assigning the dereferenced value to LHS.
a is a pointer here, pointing to an int.
*a retrieves the integer value stored at memory pointed to by a. When you say *a = <some value>, assuming <some value> to be an int, <some value> gets stored at memory location pointed to by a.
*a = *b ==> Here b is again an int pointer, so integer value pointed to by b is read and written to memory location pointed to by a.
It has no relation with '=' operator .It(* operator) just means value at 'a's address.So
t = *a; assigns value at address a to t
*a = *b; assigns b's value in place of value at address a
*b = t; assigns t to b's value
What is the difference between = *a and *a =?
Well... look at this code:
int x;
t = x;
x = t;
If you have any plain variable int x; then you can read from it and write to it. That's the difference between your two lines as well.
* is the "contents of" operator. If a is a pointer to int, then *a simply means that you can use the contents of that variable as if it had been a plain int variable. And just like any variable you can either read or write to it.

If p is a pointer to int where would one use &p

In the following code p is pointer to an int. It is quite clear that p points to the address of i. Through my research i know &p points to the address of pointer p. But i don't get why would you need separate address for that. And also when would you use &p.
int main() {
int i = 3, *p = &i;
printf("%p",&p);
printf("%p",p);
return 0;
}
If p is pointer to int then
int **q = &p;
When you want to use pointer to pointer, then use the address of a single pointer to assign it to pointer to pointer.
Just to make a point that pointer is also a data-type and it stored in the memory location and it holds a valid memory location as its value. The address in which this valid memory location is stored is given by &p
Your printf() also needs to be fixed. %p expects void *
printf("%p",(void *)p);
But i don't get why would you need separate address for that
You don't, but there exists the address of operator so you can take the address of a pointer, which is what
printf("%p\n", &p);
is printing.
And also when would you use &p
There are cases where this might be useful, consider for example that you need to pass a pointer to a function which could be reassigned into the function, you can do something like this
int allocateIntegerArray(int **pointerToPointer, size_t someSize)
{
if (pointerToPointer == NULL)
return 0;
*pointerToPointer = malloc(someSize * sizeof(int));
return (*pointerToPointer != NULL);
}
then you could use this funciton the following way
int *pointer;
if (allocateIntergerArray(&pointer, 10) == 0)
{
fprintf(stderr, "Error, cannot allocate integer array\n");
/* do some extra cleanup or recover from this error, or exit() */
exit(0);
}
The pointers themselves are also variables and as such they need to be sotred somewhere, so the address of a pointer tells you where is the pointer stored, it's value tells you where it is pointing to.
By knowing where it is stored you can do things like the one explained above.
A trivial example:
int nochange(int *c, int *val)
{
c = val; // Changes local pointer c to point to val
// Note that C passes copies of the arguments, not actual references.
}
int do_change(int **c, int *val)
{
*c = val; // Accesses the real pointer c at its real location and makes
// that one point to val
// Even though c is a pointer-to-pointer copy, its value is
// copied too, and the value is the address of the real c
}
int main()
{
int a = 1;
int b = 2;
int *c = &a; // A pointer is also a datatype that resides in memory
printf("%d\n", *c); // Will print 1
nochange(c, &b);
printf("%d\n", *c); // Will print 1
do_change(&c, &b);
printf("%d\n", *c); // Will print 2 because c now points to b
}
I have a similar answer with a bit more detail here about pointer vs pointer-to-pointer: pointer of a pointer in linked list append

Why do these pointers cause a crash?

I'm a bit confused as to why the following code crashes:
int main(){
int *a;
int *b;
*a = -2;
*b = 5; //This line causes a crash on my system.
return 0;
}
Shouldn't memory automatically be allocated for two pointers and two integers before run-time because of the declarations?
Or must you always explicitly allocate memory?
No. You've only declared the pointers, not what they point to. The pointers are allocated on the stack, and since you've not initialized them to anything, their values are garbage.
int main() {
int a = 7;
int *p_a; // p_a contains whatever garbage was on the stack at its
// location when main() is called. (Effectively points nowhere).
p_a = &a; // p_a points to (gets the address of) variable a, also on
// the stack.
printf("Before: a = %d\n", a); // prints 7
*p_a = -2;
printf("After: a = %d\n", a); // prints -2
return 0;
}
I would code up the above example, and step through it in a debugger. You'll see what I mean about what p_a is pointing to.
Shouldn't memory automatically be allocated for two pointers and two integers before run-time because of the declarations?
I only see you specifying two pointers. Where are the two integers?
Or must you always explicitly allocate memory?
Pointers have to point to something. Either local variables on the stack, or malloc'd memory from the heap.
In this code:
int* a;
*a = -2;
a is an uninitialized pointer, dereferencing of which produces undefined behavior, that you were luckily able to observe as a crash of your application.
You need to initialize the pointer (make it point to the valid memory) before you dereference it (i.e. before you use *, the dereference operator):
int a;
int* pA = &a;
*pA = -2;
Consider
int m;
int n;
m = n;
This is invalid because you're trying to use n but you haven't assigned a value to it. Now:
int *a;
*a = -2;
Likewise, this is invalid because you're trying to use a but you haven't assigned a value to it. The value of a is not an int, it's a pointer to int. For example,
int someint;
a = &someint;
*a = -2;
puts -2 into someint. Without the assignment to a, the place to put -2 is undeterminable. Also,
a = malloc(sizeof(int));
*a = -2;
Here, a is given the value of the address of some location in the heap; -2 goes into that heap location.
Perhaps an analogy would be helpful:
Consider the phrase "her dog". This is a reference to someone's' dog, but it won't do to tell me "give her dog a bone" if you haven't told me who she is. Similarly, "pointer to an int" doesn't tell the system which int it is.
Your *a and *b pointers are not initializated properly.
Try this one:
int my_a;
int my_b;
int *a;
int *b;
a = &my_a; // init the pointer a to the direction of my_a int variable
b = &my_b;
*a = 3; // set the my_a value via pointer
*b = 2;
You have just declared pointers but you haven't initialized them. So, you can't be sure that *b = 5 is causing the program to crash. It could be *a = -2 as well. To fix it, you should initialize your pointers as well.
int aval = -2;
int bval = 5;
int *a = &aval; // declared and initialized pointers
int *b = &bval;
// Now you can change the value using the pointer
*a = 15;
*b = 20;

Simple swap function...why doesn't this one swap?

I'm new to C and still trying to grasp the concept of pointers. I know how to write a swap function that works...I'm more concerned as to why this particular one doesn't.
void swap(int* a, int* b)
{
int* temp = a;
a = b;
b = temp;
}
int main()
{
int x = 5, y = 10;
int *a = &x, *b = &y;
swap(a, b);
printf(“%d %d\n”), *a, *b);
}
You're missing *s in the swap function. Try:
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
That way, instead of just swapping the pointers, you're swapping the ints that the pointers are pointing to.
Your swap() function does work, after a fashion - it swaps the values of the variables a and b that are local to swap(). Unfortunately, those are distinct from the a and b in main() - so you don't actually see any effect from swapping them.
When thinking about pointers, you need to be clear on a few abstractions.
An object in memory. This can be of any type (and size). An integer object, for example, will occupy 4 bytes in memory (on 32 bit machines). A pointer object will occupy 4 bytes in memory (on 32 bit machines). As should be obvious, the integer object holds integer values; a pointer object holds addresses of other objects.
The C programming language lets symbols (variables) represent these objects in memory. When you declare,
int i;
the symbol (variable) i represents some integer object in memory. More specifically, it represents the value of this object. You can manipulate this value by using i in the program.
&i will give you the address of this object in memory.
A pointer object can hold the address of another object. You declare a pointer object by using the syntax,
int* ptr;
Just like other variables, the pointer variable represents the value of an object, a pointer object. This value just happens to be an address of some other object. You set the value of a pointer object like so,
ptr = &i;
Now, when you say ptr in the program, you are referring to its value, which is the address of i. But if you say *ptr, you are referring to not the value of ptr, but rather the value of the object whose address is in ptr i.e. i.
The problem with your swap function is that you are swapping values of pointers, not the values of objects that these pointers hold addresses for. To get to the values of objects, you would have to use *ptr.
C is a pass-by-value language. Your swap routine doesn't dereference the pointers passed to it, so from main's perspective nothing has happened.
The pointers are passed by value. This means a & b are still a and b when the come back from the function;
try something like this
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
The right way to do it:
void swap(int* a, int* b)
{
int temp = *a; // Temp is set to the value stored at a (5)
*a = *b; // value stored at a is changed to the value stored at b (10)
*b = temp; // value stored in address b is changed to 5.
}
It does swap. It swaps local pointers a and b inside swap function. It swaps them perfectly fine, as it should.
If you want to swap the values these pointers are pointing to, you should re-implement your swap function accordingly, i.e. make it swap the pointed values, not the pointers.
Umm maybe using this
void swap(int** a, int** b)
{
int** temp = a;
a = b;
b = temp;
}
int main()
{
int x = 5, y = 10;
int *a = &x, *b = &y;
swap(&a, &b);
printf(“%d %d\n”), *a, *b);
}
Without using a third variable (temp)
void swap(int* a,int* b)
{
// a = 10, b = 5;
*a = *a + *b; // a now becomes 15
*b = *a - *b; // b becomes 10
*a = *a - *b; // a becomes 5
}
zildjohn1's answer is the easiest and clearest way to do it. However if you insist on swapping the pointers, then you have to pass the pointer to the pointer because the pointer itself is passed by value.
You need to send the address of a and b for swap function so while calling swap function you must call ass swap (&a,&b)
So that you pass the address, and alter the address
#define SWAP(a,b) ((a)=(b)+(a),(b)=(a)-(b),(a)=(a)-(b))
Works good.

Resources