Value of output is different (pointer) [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
#include<iostream>
using namespace std;
void HardToFollow(int *p, int q, int *num);
void HardToFollow(int *p, int q, int *num) {
*p = q + *num;
*num = q;
num = p;
p = &q;
cout << *p << " " << q << " " <<*num<<endl;
// value is ``1 1 4
}
main() {
int *q;
int trouble[3];
trouble[0] = 1;
q = &trouble[1];
*q = 2;
trouble[2] = 3;
HardToFollow(q, trouble[0], &trouble[2]); // 2 1 3
cout << *q << " " << trouble[0] << " " << trouble[2]<<endl;
// value become 4 1 1}
Hi everyone i am beginner to stackoverflow and I really don't get why my first output in HardToFollow function, the value is 1, 1 and 4.
But when it comes to main function output it become 4, 1 and 1. I spent much time try to understand but I can't.
Hopefully someone can help me here.

Let's look at what HardToFollow() receives and follow its flow line-by-line.
[I'll just note right here that this code is, in fact, very hard to follow, so it's possible I've made a mistake. Please follow my logic carefully to see if you agree.]
At the start of HardToFollow():
q-in-main = address of trouble[1] (value = 2)
p = address of trouble[1] (value = 2)
q-in-HardToFollow = copy of value of trouble[0] = 1
num = address of trouble[2] (value = 3)
Note that p and q-in-main are not the same variable. They are two separate pointers that point to the same location. This is because (as I'm sure is one of the points of this exercise): Variables, including pointers are passed as copies. So if you send a pointer, a new copy of the pointer is created.
*p = q + *num;
The value of the location pointed to by p is set to q-in-HardToFollow plus the value of the location pointed to by num. This is 1 plus 3, which is 4. q-in-main also points to the same location as p, so its value will also change. So now:
q-in-main = address of trouble[1] (value = 4)
p = address of trouble[1] (value = 4)
*num = q;
The value of the location pointed to by num is set to q-in-HardToFollow, which is 1. So now:
num = address of trouble[2] (value = 1)
num = p;
num is now set to point to the same location as p, that is, trouble[1]. So:
num = address of trouble[1] (value = 4)
p = &q;
p is now set to point to the location of q-in-HardToFollow. So:
p = address of q-in-HardToFollow (value = 1)
So the current addresses and values are:
q-in-main = address of trouble[1] (value = 4)
p = address of q-in-HardToFollow (value = 1)
q-in-HardToFollow = copy of value of trouble[0] = 1
num = address of trouble[1] (value = 4)
This works out well with the output you are getting.

Related

Why is the *= operator not functioning the way I would expect it to?

#include <iostream>
using namespace std;
int main ()
{
//If a triangle has a perimeter of 9 units, how many iterations(each iteration is 4/3 as much) would it take to obtain a perimeter of 100 units? (or as close to 100 as you can get?)
double p = 9; int it = 0;
for(p; p < 100; p = p * 4/3){
cout << p << endl;
it++;
}
cout << p << endl;
cout << it << endl;
system ("PAUSE");
return 0;
}
So for a math project I was doing, I had to figure out how many iterations it would take for a perimeter of 9 to reach 100 if you increase the perimeter 4/3x as much during each iteration. When I write the code like I do above, the output is fine, however if I change
for(p; p < 100; p = p * 4/3)
to
for(p; p < 100; p *= 4/3)
I get output that doesn't make sense. Am I misunderstanding the *= operator? Do I need parentheses somewhere?
It's the order of operation. In p = p * 4/3 the compiler is doing:
p = (p * 4)/3
However in p *= 4/3, the compiler is doing:
p = p * (4/3)
4/3 is 1 on the computer because of integer division, so the second example is basically multiplying by 1.
Instead of dividing by 3 (an integer), divide by 3.0 (a double) or 3.0f (a float). Then p *= 4/3.0 and p = p * 4/3.0 are the same.

C++ double ptr to long ptr conversion

Consider the below code fragment:
double * p = new double[16];
int value = 1;
void * q = p;
*((double *)q) = value;
int x = ((long *)p)[0];
cout << "Value of x for double * to long * = " << x << endl;
*((int *)q) = value ;
x = ((long *)p)[0];
cout << "Value of x for int * to long * = " << x << endl;
Here the outputs are 0 and 1 respectively. Can anyone explain to me why?
Also if I directly access the value at pointer...ie. p[0], the value is correctly shown as 1 in both case. Why?
Integers are stored in memory in straight binary so you can convert between intand long with no problem. doulbe is stored using the floating point binary syntax where some of the bits are used to describe the mantissa and the others are used to describe the exponent (similar to scientific notation i.e. 5e2 = 500).
If you try and use the data for a double as the data for a double then it will not convert correctly due to the different ways that the binary stores the value.

Passing pointers to function does not return value

In following case I get NumRecPrinted = 0 , that is num is 0
int main()
{
int demo(int *NumRecPrinted);
int num = 0;
demo(&num);
cout << "NumRecPrinted=" << num; <<<< Prints 0
return 0;
}
int demo (int *NumRecPrinted)
{
int no_of_records = 11;
NumRecPrinted = &no_of_records;
}
You are assigning the address to the pointer, and not the value to the pointed-to. Try it like this instead
int demo (int *NumRecPrinted)
{
int no_of_records = 11;
*NumRecPrinted = no_of_records;
}
No!
*NumRecPrinted = no_of_records;
See "*" means "value of" and "&" means "address of". You want to change the "value of" NumRecPrinted, which is why the above works. What you did was to give NumRecPrinted the "address of" num_of_records.
All you did was pointer the local pointer-to-int NumRecPrinted at a new integer inside the demo function.
You want to change the integer it points to, not change where it points.
*NumRecPrinted = no_of_records;
You can see in your version that you're taking the address of a local variable, and you know it isn't the address of that variable you care about, but its value.
As others have pointed out, the * = the value of and & = address of. So you were just assigning a new address to the pointer inside the method. You should:
*NumRecPrinted = no_of_records;
See this excellent tutorial on Pointers. E.g.:
int firstvalue = 5, secondvalue = 15;
int * p1, * p2;
p1 = &firstvalue; // p1 = address of firstvalue
p2 = &secondvalue; // p2 = address of secondvalue
*p1 = 10; // value pointed by p1 = 10
*p2 = *p1; // value pointed by p2 = value pointed by p1
p1 = p2; // p1 = p2 (value of pointer is copied)
*p1 = 20; // value pointed by p1 = 20
You want
*NumRecPrinted = no_of_records;
That means, "set the thing NumRecPrinted points to to equal no_of_records".

memory location of pointer variable itself?

Is it possible to find the memory location of a pointer variable itself?
i.e. I don't want to know the memory location the pointer is referencing, I want to know what the memory location of the pointer variable is.
int A = 5;
int *k = &A;
cout << k;
will give me the location of A. Does k have a location?
The location of int *k is &k, like so:
// For this example, assume the variables start at 0x00 and are 32 bits each.
int A = 9; // 0x00 = 0x09
int * k = &A; // 0x04 = 0x00
int ** k_2 = &k; // 0x08 = 0x04
// Thus:
cout << "Value of A: " << A; // "Value of A: 9"
cout << "Address of A: " << k; // "Address of A: 0x00"
cout << "Address of k: " << k_2; // "Address of k: 0x04"
assert( A == *k);
assert(&A == k);
assert(&A == *k_2);
assert( A == **k_2);
assert( k == *k_2);
assert(&k == k_2);
A pointer is a variable, 32-bit on 32-bit binaries and 64 in 64, storing a memory address. Like any other variable, it has an address of its own, and the syntax is identical. For most intents and purposes, pointers act like unsigned ints of the same size.
Now, when you take &k, you now have an int **, with all the interesting complexities that go with that.
From int ** k_2 = &k, *k_2 is k and **k_2 is *k, so everything works about how you'd expect.
This can be a useful way to handle creating objects cross-library (pointers are rather fundamental and mostly safe to pass). Double pointers are commonly used in interfaces where you want to pass a pointer that will be filled with an object, but not expose how the object is being created (DirectX, for example).
Yes. You can use &k to print out the memory location of *k.
int A = 5;
int *k = &A;
cout << k;
A's address is k;
k's address is &k.
Yo dawg, we put an address at your address so you can address while you address.

Pointer to pointer array understanding problem

This is probably a stupid question, but I don't understand why this works:
int** test = new int*[7];
int x = 7;
*(test+1) = &x;
cout << (**(test+1));
test is a pointer to a pointer right? The second pointer points to the array, right?
In my understand I would need to dereference the "test" pointer first to get to the pointer that has the array.
(*test) // Now I have int*
*((*test) + 1) // to access the first element.
Where is my faulty thinking?
int** test = new int*[7];
+------++------++------++------++------++------++------+
| int* || int* || int* || int* || int* || int* || int* |
+------++------++------++------++------++------++------+
is the equivalent of an array with int pointers:
int* test[0]
int* test[1]
...
int* test[6]
this
int x = 7;
*(test+1) = &x;
+------++------++------++------++------++------++------+
| int* || &x || int* || int* || int* || int* || int* |
+------++------++------++------++------++------++------+
is the same as
int x = 7;
test[1] = &x
so now one of the pointers in your original array is pointing the memory location of x
cout << (**(test+1));
is the same as
cout << *test[1]
which is the value of x (==7) and which both test[1] and &x point to.
Is your misunderstanding that you think you have created a pointer to an array of 7 int? You haven't. You actually have created an array of 7 pointers to int. So there is no "second pointer" here that would point to an array. There is just one pointer that points to the first of the 7 pointers (test).
And with *test you get that first pointer which you haven't initialized yet, though. If you would add 1 to that, you would add 1 to some random address. But if you add 1 to test you get a pointer that points to the second pointer of the array. And dererencing that you get that second pointer, which you did initialize.
What you describe would be achieved by a different syntax
typedef int array[7];
array* test = new int[1][7];
// Note: "test" is a pointer to an array of int.
// There are already 7 integers! You cannot make it
// point to an int somehow.
*(*test + 1) = 7;
int *p1 = *test
int i1 = *(p1 + 1); // i1 is 7, second element of the int[7]
delete[] test;
Without using the typedef, this looks like the following
int(*test)[7] = new int[1][7];
That is, you have created a one-element array, where the element-type of that is a 7-element array of int. new gives you a pointer back to that array. Note that the parenthesis is important: The * has less precedence than the [7], so otherwise this would be taken as an array of 7 pointer to integers.
Suppose that
test[0] = 0x12345678; // some pointer value
test[1] = 0x23456789; // some pointer value
*test = 0x12345678;
*test + 1 is now 0x12345678 + 1 = 0x12345679;
* or dereference operator has higher precedence than binary +). So the expression is evaluated in that order.
However what you wanted for is to get to test[0] = 0x23456789;
So the correct expression to get to test[1] = (*(test + 1))
In general arr[i] is *(arr + i)
EDIT 2:
given
int buf[10] = {0, 1, 2};
int *p = buf;
buf[0] == p[0] == *(p + 0) equal to 0.
Note that it is perfectly fine to use array access syntax with the lvalue expression p even if it is not an array type. In fact the expression buf[0] is internally translated by the compiler to *(buf + 0) as well.
The expression *(test + 1) is equivalent to test[1], so your code could be rewritten thus:
int** test = new int*[7];
int x = 7;
test[1] = &x;
cout << *test[1];
Since test[1] obviously points to x, *test[1] is 7.
Just to be clear, the expression **(test + 1) is simply equivalent to *(*(test + 1)), which is in turn equivalent to *test[1].