C++ Swapping Pointers - c++

I'm working on a function to swap pointers and I can't figure out why this isn't working. When I print out r and s in the swap function the values are swapped, which leads me to believe I'm manipulating a copy of which I don't understand because I pass by reference of p and q.
void swap(int *r, int *s)
{
int *pSwap = r;
r = s;
s = pSwap;
return;
}
int main()
{
int p = 7;
int q = 9;
swap(&p, &q);
cout << "p = " << p << "q= " << q << endl;
return 0;
}
Prints: p = 7q = 9

Inside your swap function, you are just changing the direction of pointers, i.e., change the objects the pointer points to (here, specifically it is the address of the objects p and q). the objects pointed by the pointer are not changed at all.
You can use std::swap directly. Or code your swap function like the following:
void swap(int *r, int *s)
{
int temp = *r;
*r = *s;
*s = temp;
return;
}

The accepted answer by taocp doesn't quite swap pointers either. The following is the correct way to swap pointers.
void swap(int **r, int **s)
{
int *pSwap = *r;
*r = *s;
*s = pSwap;
}
int main()
{
int *p = new int(7);
int *q = new int(9);
cout << "p = " << std::hex << p << std::endl;
cout << "q = " << std::hex << q << std::endl << std::endl;
swap(&p, &q);
cout << "p = " << std::hex << p << std::endl;
cout << "q = " << std::hex << q << std::endl << std::endl;
cout << "p = " << *p << " q= " << *q << endl;
return 0;
}
Output on my machine:
p = 0x2bf6440
q = 0x2bf6460
p = 0x2bf6460
q = 0x2bf6440
p = 9 q= 7

The line r=s is setting a copy of the pointer r to the copy of the pointer s.
Instead (if you do not want to use the std:swap) you need to do this
void swap(int *r, int *s)
{
int tmp = *r;
*r = *s;
*s = tmp;
}

You passed references to your values, which are not pointers. So, the compiler creates temporary (int*)'s and passes those to the function.
Think about what p and q are: they are variables, which means they are slots allocated somewhere in memory (on the stack, but that's not important here). In what sense can you talk about "swapping the pointers"? It's not like you can swap the addresses of the slots.
What you can do is swap the value of two containers that hold the actual addresses - and those are pointers.
If you want to swap pointers, you have to create pointer variables, and pass those to the function.
Like this:
int p = 7;
int q = 9;
int *pptr = &p;
int *qptr = &q;
swap(pptr, qptr);
cout << "p = " << *pptr << "q= " << *qptr << endl;
return 0;

You are not passing by reference in your example. This version passes by reference,
void swap2(int &r, int &s)
{
int pSwap = r;
r = s;
s = pSwap;
return;
}
int main()
{
int p = 7;
int q = 9;
swap2(p, q);
cout << "p = " << p << "q= " << q << endl;
return 0;
}
Passing by reference is not the same as passing by value or by pointer. See C++ tutorials on the web for an explanation. My brain is too small to waste cells storing the fine details I can find on the web easily.

If you are into the dark arts of C I suggest this macro:
#define PTR_SWAP(x, y) float* temp = x; x = y; y = temp;
So far this has worked for me.

Related

Grabbing the address of the pointer variable itself, instead of the address that we are pointing to, in C/C++?

Let's consider I have the following x pointer variable in my function:
int* x = new int { 666 };
I know I can print its value by using the * operator:
std::cout << *x << std::endl;
And that I can even print the address of where the 666 is being stored on the heap, like this:
std::cout << (uint64_t)x << std::endl;
But what I'd like to know is on whether it's also possible to grab the address of the x variable itself, that is, the address of the region of memory in the stack containing the pointer to the heap int containing 666?
Thanks
Just use another &
std::cout << (uint64_t)&x << std::endl;
e.g.:
int v = 666; // variable
int * x = &v; // address of variable
int ** p = &x; // address of pointer x
and so on
int *** pp = &p;
int **** ppp = &pp;
and how to access to it:
std::cout << ****ppp << " == " << ***pp << " == "
<< **p << " == " << *x << " == " << v << std::endl;

Char pointer assignment not working

I have piece of code here.
void MyString::rm_left_space(char *s){
int size = getSize(s);
char s2[size];
char *s1=&s2[0];
int i=0;
while(*(s+i)==' '){
i++;
}
for (int k=i,l=0; k<size; k++) {//start from i, discarding spaces
*(s1+l) = *(s+k);
l++;
}
s=s1;
}
void MyString::rm_right_space(char *s){
int countSpacesfromLast=0;
int size = getSize(s);
int j=size-1;
while(*(s+j)==' '){
countSpacesfromLast++;
j--;
}
char *s2=new char[size-countSpacesfromLast];
for (int t=0; t<size-countSpacesfromLast; t++) {
*(s2+t)=*(s+t);
}
s=s2;
}
void MyString::rm_space(char *s){
rm_left_space(s);
rm_right_space(s);
}
Where there is s=s1 and s=s2 assignment does not happen. How come pointer assignment is not working.
In rm_space method s is unchanged after function calls. Why?
In rm_space method s is unchanged after function calls. Why?
Because s is passed by value. In other words - it's not the variable s that is passed but the value that s holds. The variable s in the called function and the variable s in the calling function are two different variables. Consequently, changes made to one of them does not change the other.
If you want to change s in the calling function inside the called function, you need to use call-by-reference.
Something like:
void MyString::rm_left_space(char*& s){
However, notice that your code have a major problem as it seems you are trying to assign s2 in the called function to s in the calling function. You should never do that as s2 goes out of scope as soon as the function returns.
Example: Difference between pass-by-value and between pass-by-value
This simple program uses pass-by-value
#include <iostream>
void foo(int x)
{
x = 42;
std::cout << "Inside foo: x=" << x << std::endl;
}
int main()
{
int x = 21;
std::cout << "Before foo: x=" << x << std::endl;
foo(x);
std::cout << "After foo: x=" << x << std::endl;
return 0;
}
The output is
Before foo: x=21
Inside foo: x=42
After foo: x=21 // notice x didn't change
because x in foo and in main are two different variables.
This simple program uses pass-by-reference
#include <iostream>
void foo(int& x) // Notice the &
{
x = 42;
std::cout << "Inside foo: x=" << x << std::endl;
}
int main()
{
int x = 21;
std::cout << "Before foo: x=" << x << std::endl;
foo(x);
std::cout << "After foo: x=" << x << std::endl;
return 0;
}
The output is
Before foo: x=21
Inside foo: x=42
After foo: x=42 // notice that x changed
because now x inside foo is a reference to x in main
These examples used int but exactly the same applies for pointers.
Example: Using pointers
#include <iostream>
int x = 21;
int y = 5;
void foo(int* p)
{
*p = 42;
p = &y;
std::cout << "Inside foo: p = " << p << std::endl;
std::cout << "Inside foo: *p = " << *p << std::endl;
}
int main()
{
int* p = &x;
printf("%p\n", (void*)p);
std::cout << "Before foo: p = " << p << std::endl;
std::cout << "Before foo: *p = " << *p << std::endl;
foo(p);
std::cout << "After foo : p = " << p << std::endl;
std::cout << "After foo : *p = " << *p << std::endl;
return 0;
}
Output:
Before foo: p = 0x60106c
Before foo: *p = 21
Inside foo: p = 0x601070
Inside foo: *p = 5
After foo : p = 0x60106c // Pointer value did NOT change
After foo : *p = 42 // Pointed to value DID change
Replacing
void foo(int* p)
with
void foo(int*& p)
will give:
Before foo: p = 0x60106c
Before foo: *p = 21
Inside foo: p = 0x601070
Inside foo: *p = 5
After foo : p = 0x601070 // Pointer value DID change
After foo : *p = 5 // Consequently, the pointed to value also changed
I am new to StackOverflow, if there's any mistake, please Kindly judge me
I am not sure that whether I was misunderstand what you mean, so if there's any misunderstanding, please let me know.
I guess you want to do remove left space in a string, right?
e.g.
" Hello" --> "Hello"
if so, here is my version
#include <iostream>
using namespace std;
#define SIZE 7
void rm_left_space(char* s){
int size = SIZE; //Because I don't know how to getSize, so I use fixed size instead
char s2[size];
char *s1 = &s2[0];
int i = 0;
while(*(s+i) == ' '){
i++;
}
cout << i << endl;
for (int k=i,l=0; k<size; k++) {//start from i, discarding spaces
*(s1+l) = *(s+k);
l++;
}
s=s1; // <-- Shallow copy
}
void rm_left_space_2(char* s){
int size = SIZE;
char *s2 = new char[SIZE]; <-- you should use dynamic array instead of static array
int space_num = 0;
while(*(s+space_num) == ' '){
space_num++;
}
for (int i = 0; i < SIZE; i++){
s2[i] = s[(i + space_num)%size];
}
// s = s2; // <--- shallow copy
for (int i = 0; i < SIZE; i++){ // You should copy whole array
s[i] = s2[i];
}
}
int main(){
char s[] = " hello";
cout << s << endl;
rm_left_space_2(s);
cout << s << endl;
return 0;
}
The output:
hello
hello
Also, you could check the post,
static array vs dynamic array in C++

Why difference between two pointers is not equals to size of type?

I have the simple program:
#include <iostream>
using namespace std;
int main()
{
int a = 5;
int b = 6;
int* p1 = &a;
int* p2 = &b;
std::cout << p1 << " " << p2 << " ,sizeof(int)=" << sizeof(int) << std::endl;
system("pause");
return 0;
}
It produces the following output:
00DBF9B8 00DBF9AC ,sizeof(int)=4
but, 00DBF9B8 - 00DBF9AC == ะก. I cannot understand this result.
If I modify the program like this:
#include <iostream>
using namespace std;
int main()
{
static int a = 5;
static int b = 6;
int* p1 = &a;
int* p2 = &b;
std::cout << p1 << " " << p2 << " ,sizeof(int)=" << sizeof(int) << std::endl;
system("pause");
return 0;
}
I got correct result:
00394000 00394004 ,sizeof(int)=4
There is no guarantee that local variables (or even static variables) are put on consecutive memory addresses. And actually it would be undefined behaviour if you substracted two pointer values that do not point into the same array.
But you could use pointer arithmetics as follows:
int main()
{
int a;
int* p1 = &a;
int* p2 = p1+1;
std::cout << p1 << " " << p2 << " ,sizeof(int)=" << sizeof(int) << std::endl;
return 0;
}
Note that a single integral value may be considered as an array of size 1, and that p1+1 therefore points to "one after the last element of an array", such that the operation p2 = p1+1 is actually valid (dereferencing p2 then would not be valid, of course).

Dereferencing double pointer, triple pointers, and so on

Below is a sample program I created to play around with pointers.
#include <iostream>
using namespace std;
void addOne(int** ptr);
void addTwo(int*** ptr);
void addThree(int**** ptr);
void addFour(int***** ptr);
int main()
{
int* ptr = nullptr;
int x = 1;
ptr = &x;
cout << "Original value of x: " << *ptr << endl;
addOne(&ptr);
cin.get();
return 0;
}
void addOne(int** ptr)
{
**ptr += 1;
cout << "After adding 1: " << **ptr << endl;
addTwo(&ptr);
}
void addTwo(int*** ptr)
{
***ptr += 2;
cout << "After adding 2: " << ***ptr << endl;
addThree(&ptr);
}
void addThree(int**** ptr)
{
****ptr += 3;
cout << "After adding 3: " << ****ptr << endl;
addFour(&ptr);
}
void addFour(int***** ptr)
{
*****ptr += 4;
cout << "After adding 4: " << *****ptr << endl;
}
The program above will give me the following output:
Original value of x: 1
After adding 1: 2
After adding 2: 4
After adding 3: 7
After adding 4: 11
Now focus on the addFour function:
void addFour(int***** ptr)
{
*****ptr += 4;
cout << "After adding 4: " << *****ptr << endl;
}
Now what I did was I reduced the number of *s in the addFour function by doing this:
void addFour(int***** ptr)
{
****ptr += 4;
cout << "After adding 4: " << ****ptr << endl;
}
When I did the above code, it gave me the following output:
Original value of x: 1
After adding 1: 2
After adding 2: 4
After adding 3: 7
After adding 4: 010EFDE0
My question then is, what is the following statements doing since I reduced the number of *s:
****ptr += 4;
cout << "After adding 4: " << ****ptr << endl;
Can someone please explain this for me?
You reduced the dereferencing in addFour to four levels, but the function still takes an int*****.
Most of your code is irrelevant and can be reduced to something like this:
int x = 1;
cout << "Original value of x: " << *&x << endl;
x += 1;
cout << "After adding 1: " << **&&x << endl;
x += 2;
cout << "After adding 2: " << ***&&&x << endl;
x += 3;
cout << "After adding 3: " << ****&&&&x << endl;
x += 4;
cout << "After adding 4: " << *****&&&&&x << endl;
So far your dereference and address-of operations cancel out. But then you're asking what this is:
cout << "After adding 4: " << ****&&&&&x << endl;
Quite simply, you have not performed the final dereference so you're left with &x, not x.
And &x is a pointer. In the example above, you'd be seeing the address of x in memory, given in hexadecimal notation. In your case, your ptr has an unspecified value because pointer arithmetic out of bounds of an object has undefined behaviour, but in practice you're printing the value of the address of x plus sizeof(int).
addOne receives the address of ptr that points to x and store it into a local variable ptr.
addTwo receives the address of addOne::ptr and store it in its local ptr variable.
addThree receives the address of addTwo::ptr and store it in its local ptr variable.
addFour receives the address of addThree::ptr and store it in its local ptr variable. Thus in addFour (second version):
*ptr is addThree::ptr,
**ptr is addTwo::ptr,
***ptr is addOne::ptr and
****ptr is main::ptr.
You then increment a pointer to int by 4, thus calculating the address of the fourth int starting from the address of x, and then print that address.
Of course, in the first version *****ptr is main::x, and you then increment int x by 4.
Trying to visualize this graphically, you have:
P -> P -> P -> P -> P -> X
X is the value, P are pointers.
Every time you write &, you move to the left, and every time you write *, you move to the right.
So if you have &&&&&x, and you increment ****x, you do this:
P -> P -> P -> P -> P -> X
\
> ?
You moved four levels to the right, and incremented the pointer there, which now points to a memory location after X.
Then you print ****x, which is a pointer, because you moved four levels to the right.
// if you want to understand pointers this is my fave example
struct block
{
int data;
struct block *next_block;
};
struct block *block_head = NULL;
add_block(int n) /* add n in the sorted position */
{
struct block *new, *prev = NULL, *bp = block_head;
new = malloc(sizeof(struct block));
new->data = n;
while(bp != NULL)
if(bp->data > n)
{
prev = bp;
bp = bp->next_block;
}
else
{
if(prev == NULL)
{
new->next_block = bp;
block_head = new;
}
else
{
new->next_block = bp;
prev->next_block = new;
}
if(block_head == NULL)
block_head = new;
else
{
prev->next_block = new;
new->next_block = NULL;
}
}
// the above is how you usually do a linked list but it's messy and ugly
// not elegant
// the elegant way to do this is with a double pointer
add_block(int n) /* add n in the sorted position */
{
struct block *new, **bp = &block_head;
new = malloc(sizeof(struct block));
new->data = n;
while(*bp != NULL)
if((*bp)->data > n)
bp = &((*bp)->next_block);
else
break;
new->next_block = *bp;
*bp = new;
}
// if you can understand the elegant version, you probably got pointers down cold.

On Pointers and Dereferencing

I've been working on learning C++ lately and picked up the book "C++ Through Game Programming". I'm on the chapter on Pointers and I've been presented an example that I have a question about. The code is this:
#include "stdafx.h"
#include <iostream>
using namespace std;
void badSwap(int x, int y);
void goodSwap(int* const pX, int* const pY);
int main()
{
int myScore = 150;
int yourScore = 1000;
cout << "Original values\n";
cout << "myScore: " << myScore << "\n";
cout << "yourScore: " << yourScore << "\n\n";
cout << "Calling badSwap()\n";
badSwap(myScore, yourScore);
cout << "myScore: " << myScore << "\n";
cout << "yourScore: " << yourScore << "\n\n";
cout << "Calling goodSwap()\n";
goodSwap(&myScore, &yourScore);
cout << "myScore: " << myScore << "\n";
cout << "yourScore: " << yourScore << "\n";
cin >> myScore;
return 0;
}
void badSwap(int x, int y)
{
int temp = x;
x = y;
y = temp;
}
void goodSwap(int* const pX, int* const pY)
{
//store value pointed to by pX in temp
int temp = *pX;
//store value pointed to by pY in address pointed to by pX
*pX = *pY;
//store value originally pointed to by pX in address pointed to by pY
*pY = temp;
}
In the goodSwap() function there's the line:
*pX = *pY;
Why would you dereference both sides of the assignment? Isn't that the equivalent of saying "1000 = 150"?
Why would you dereference both sides of the assignment? Isn't that the equivalent of saying "1000 = 150"?
No, just like the following:
int x = 1000;
int y = 150;
x = y;
is not the equivalent of saying "1000 = 150". You're assigning to the object, not to the value it presently contains.
The below is precisely the same (since the expression *px is an lvalue referring to the object x, and the expression *py is an lvalue referring to the object y; they're literally aliases, not some strange, disconnected version of the objects' numerical values):
int x = 1000;
int y = 150;
int* px = &x;
int* py = &y;
*px = *py;
*px=*py means we are assigning the value not address, from address of py to address of px.
Skip the chapter of the book or buy another one:
there is no need of using plain pointers in C++ nowadays.
Also there is a std::swap function, that does the things C++isch.