C++ : pointers to stack-dynamic variables - c++

I am new to C++. I don't quite understand why this code does not work. What does this code have to do with stack-dynamic variable? Thanks for your help.
int twice(int x)
{
int *y;
*y = x * 2;
return *y;
}

int *y;
*y = x * 2;
is not correct because y points nowwhere, not into an allocated memory. It is undefined behavior. After this line of code your program is completely unpredictable and you cannot assume anything about its behavior.
You need to allocate the memory first using new or malloc and assign x*2 to it or pass an address to assign y into, i.e:
int *y = new int( x * 2);
Example:
int main() {
int x = 4;
int *y = new int( x * 2);
cout << x << "," << *y;
delete y;
return 0;
}
Side note: this is dangerous to return a pointer to memory allocated in function because this might become unclear who and when is responsible for freeing allocated memory. In your particular case there is absolutely no apparent reason for dynamic allocation by the way.

Related

What is meaning of (*x++) in c++?

#include <iostream>
using namespace std;
class base {
public:
int* x, y;
base(int xx = 0, int yy = 0) {
x = new int[4];
for (int i = 0; i < 4; i++)
x[i] = 1;
(*x++) = xx;
y = yy++;
}
~base() { delete[] x; }
};
class Derived :public base {
public:
Derived(int xx, int yy) : base(xx), base1(yy) {
cout << (*(this->x)) << " " << this->y << " " << (*
(base1.x)) << " " << base1.y << " ";
}
~Derived() {}
private:
base base1;
};
int main() {
Derived objDev(32, 33);
return 0;
}
I have problem with understand it.
Because i think it should give output as "33 0" but gave "1 0" and also i write in some std::cout for controlling in constructor body, and saw x[3] is -33686019 after '''(*x++) = x; ''' part. How could it be possible? how *x++ can change x[3] and why is this value?
and also compiler give error. doesn't *x++ mean what is x point, increase it? so when after assign xx to (*x++) wouldn't it be 32+1=33?
please help
x = new int[4]; creates an array of 4 int and sets x to point to the beginning of them. Because x is going to change, let’s call this array A, which will not change.
Then x[0] refers to the first element of this array, x[1] is the second, x[2] is the third, and x[3] is the fourth. So far x[0] and A[0] are the same thing, and so are the pairs x[1] and A[1], x[2] and A[2], and x[3] and A[3].
(*x++) is grouped as ( * (x++) ). x++ does two things. It produces the value of x, and, as a side effect, it increments x. Since x++ produces the value of x, *(x++) is the int that x points to before the increment.
This means that (*x++) = xx; stores x in the first element of the array, but it changes x to point to the second element, which is A[1].
Once x points to the second element, then x[0] is A[1], x[1] is A[2], x[2] is A[3], and x[3] is beyond the end of the array. x[-1] would be A[0].
So, where the code sends (*(this->x)) to cout, it is sending A[1], which has 1 in it. That explains why you got output of “1”.
When you looked at x[3], you were looking beyond the array. What is there could be some other value the program has worked with, completely unrelated to what is in the array. But accessing an element beyond array bounds can cause various problems with programs other than just giving a wrong value.
In the destructor, delete[] x; is wrong because x has been changed and no longer has the original address of the array. You could use delete [] --x; or delete [] x-1; to recalculate the original address. However, if a program has some need to use a pointer into the middle of an array, it is more common to store the base address and never change it and create a separate pointer into the middle. That is usually less error prone and easier for other programmers to follow.

Setting a variable equal to a variable that is equal to nullptr

I have an array called my_array of linked lists.
Node* x = my_array[0];
if (head == nullptr)
{
my_array[0] = new Node;
}
How come this one works fine, but
Node* x = my_array[0];
if (head == nullptr)
{
x = new Node;
}
how come this one leaks memory? Aren't they pointing to the same thing? They should be the same, right?
You misunderstood how pointers work. Pointers are variables like any other and their value is a memory address. Nothing more and nothing less.
This line:
Node* x = my_array[0];
Copies the address from my_array[0] to a new variable called x. While the address is the same, the x and my_array[0] are not the same thing. They are two distinct variables holding the same address.
This line:
my_array[0] = new Node;
Re-assigns the address of my_array[0] to a new address of the heap allocated Node object. It overwrites the old address in my_array[0] and thus leaks the memory because the address (and the object in it) was never freed. However you still have it in x so you can still free it and prevent the leak.
This line:
x = new Node;
does essentially the same thing but overwrites the address stored in x instead. This might be fine though because the original address is still in my_array[0] (remember x was just copy of that address) and might be freed later. And also you can still free the new address in x as well too. So the second one might not leak either.
I highly recommend you to watch POINTERS by TheCherno. It is excellent and simple explanation.
x is a variable on its own and it is not an alias for my_array[0]. Changing x only affects the value of x.
Example:
int zero = 0;
int one = 1;
int* arr[] = {&zero};
int* x = arr[0];
x = &one;
std::cout << "*arr[0] = " << *arr[0] << '\n'
<< "*x = " << *x;
Output:
*arr[0] = 0
*x = 1
As you can see, what x points to is changed but the array is not affected. Now, if you want an alias, you should use a reference:
int* arr[] = {&zero};
int*& x = arr[0];
x = &one; // note the &
std::cout << "*arr[0] = " << *arr[0] << '\n'
<< "*x = " << *x;
Output:
*arr[0] = 1
*x = 1
Meaning you should use Node *&x = my_array[0]; or with modern C++, auto& x = my_array[0];.

confused about pointers

I just started learning c++ (I'm more of a java developer right now) and am having some confusion with using pointers... for example, the following code works
int main() {
int x = 5;
int * y;
y = &x; //note this line of code
*y = 10;
}
whereas this code does not work
int main() {
int x = 5;
int * y;
y = x;
*y = 10;
}
Can someone explain to me why getting the value "location" using y = &x works but as soon as I replace it with y = x it causes an error. If anyone knows of a good explanation on pointers please share the link :)
Thank you!
Let's see how this works with pointers.
int x = 5;
You're assigning the value 5 to x which is an int.
int *y;
You're declaring a pointer to an int.
y = &x;
Now, the address stored in y is the same as the address of x.
But, if you do this : y = x, you're assigning an integer (5 in that case) to a variable that holds addresses of integers.
Finally, you have to remember that :
& is the address-of operator, and can be read as "address of"
* is the indirection operator, and can be read as "value pointed to by"
Tutorial about pointers
a pointer is a variable that holds a memory location. In your instance, the variable "x" holds the value 5, where the variable y holds a location in memory. the "&" operator will enable you to use the location in memory of the "x" variable
cout >> x; //will give you an output of 5.
cout >> &x; //will give you an output of the memory location of the variable x.
y = &x;
cout >> y; //will give you an output of the memory location of the variable x.
y is a pointer to an int. x is an int. Therefore whenever you set y=x you are telling y that whenever it gets dereferenced, it should go looking at memory location 10 (or whatever x is at assignment time). And there probably isn't a memory allocation at 10. Or at least not what you are expecting. If you want to get the location of x, get a pointer to it with &x.
int main() {
int x = 5;
int * y;
y = &x; // <-- NOTE THE "&" WHICH MEANS GET REFERENCE
*y = 10;
}

c++ passing Pointers into a function, for passing int arrays out of and into a function

I am trying to pass an int array around. Below is an example of what I want to do. Basically, I can write a function that returns an int array by returning a pointer. Now I want to take that function and use it as an argument to another function. The goal is to have one function create an int array and then this goes into another function that takes an int array as an input. It doesn't work. Inside the function that takes the int * pointer, the int * pointer just becomes -8435432 and can't have its elements read after it is assigned to another int * pointer. I don't get it. Why can I get an int array back from a function but this can't then be used as an input to another function?
int * returnIntArray()
{
int * thePointer;
int j[3];
thePointer = j;
j[0] = 1;
j[1] = 3;
j[2] = -1;
return thePointer;
}
//
int * takesTheIntArray(int * anIntArray)
{
int x,y,z;
int * returnIt;
returnIt = anIntArray;
x = returnIt[0];
y = returnIt[1];
z = returnIt[3];
return returnIt;
}
int _tmain(int argc, _TCHAR* argv[])
{
int y,z,p;
int * x;
x = returnIntArray();
y = x[0];
z = x[1];
x = takesTheIntArray(returnIntArray());
cout << x[0] << ", " << x[1];
//cout << theVector[1];
cout << "hello";
}
int * thePointer;
int j[3];
thePointer = j;
Should be:
int* thePointer = new int[3];
The problem with the first version is that you're returning something that is statically allocated (allocated on the stack). It will go out of scope when the function returns. In the second version it's dynamically allocated (allocated on the heap). Remember to call delete[] on thePointer once you're finished (or else you leak memory).
You can rewrite returnIntArray() as following:
int * returnIntArray()
{
static int j[3];
j[0] = 1;
j[1] = 3;
j[2] = -1;
return j;
}
You don't need the "thePointer" variable that only hides the fact that your j was a local variable destroyed at the end of the scope. You may have tried without the "thePointer" variable and obtained a "warning C4172: returning address of local variable or temporary" meaning the value you return won't be valid after returning (the same problem you have with thePointer). The static before j declaration makes the j global (but only available by its name in the function) so values contained by j won't be lost at the end of the scope.
I did not understand what was the point of "takesTheIntArray" maybe a debug purpose to see x, y, z values in debugger? if this is the case you don't need to copy the pointer and can simply do:
//
int * takesTheIntArray(int * anIntArray)
{
int x,y,z;
x = anIntArray[0];
y = anIntArray[1];
z = anIntArray[2];
return anIntArray;
}
Keep your main and this should work as you want :)
[edit] there was a typo in the "takesTheIntArray" I didn't noticed when reposting: the anIntArray index for z var should be 2 and not 3[/edit]

How to convert int* to int

Given a pointer to int, how can I obtain the actual int?
I don't know if this is possible or not, but can someone please advise me?
Use the * on pointers to get the variable pointed (dereferencing).
int val = 42;
int* pVal = &val;
int k = *pVal; // k == 42
If your pointer points to an array, then dereferencing will give you the first element of the array.
If you want the "value" of the pointer, that is the actual memory address the pointer contains, then cast it (but it's generally not a good idea) :
int pValValue = reinterpret_cast<int>( pVal );
If you need to get the value pointed-to by the pointer, then that's not conversion. You simply dereference the pointer and pull out the data:
int* p = get_int_ptr();
int val = *p;
But if you really need to convert the pointer to an int, then you need to cast. If you think this is what you want, think again. It's probably not. If you wrote code that requires this construct, then you need to think about a redesign, because this is patently unsafe. Nevertheless:
int* p = get_int_ptr();
int val = reinterpret_cast<int>(p);
I'm not 100% sure if I understand what you want:
int a=5; // a holds 5
int* ptr_a = &a; // pointing to variable a (that is holding 5)
int b = *ptr_a; // means: declare an int b and set b's
// value to the value that is held by the cell ptr_a points to
int ptr_v = (int)ptr_a; // means: take the contents of ptr_a (i.e. an adress) and
// interpret it as an integer
Hope this helps.
use the dereference operator * e.g
void do_something(int *j) {
int k = *j; //assign the value j is pointing to , to k
...
}
You should differentiate strictly what you want: cast or dereference?
int x = 5;
int* p = &x; // pointer points to a location.
int a = *p; // dereference, a == 5
int b = (int)p; //cast, b == ...some big number, which is the memory location where x is stored.
You can still assign int directly to a pointer, just don't dereference it unless you really know what you're doing.
int* p = (int*) 5;
int a = *p; // crash/segfault, you are not authorized to read that mem location.
int b = (int)p; // now b==5
You can do without the explicit casts (int), (int*), but you will most likely get compiler warnings.
Use * to dereference the pointer:
int* pointer = ...//initialize the pointer with a valid address
int value = *pointer; //either read the value at that address
*pointer = value;//or write the new value
int Array[10];
int *ptr6 = &Array[6];
int *ptr0 = &Array[0];
uintptr_t int_adress_6 = reinterpret_cast<uintptr_t> (ptr6);
uintptr_t int_adress_0 = reinterpret_cast<uintptr_t> (ptr0);
cout << "difference of casted addrs = " << int_adress_6 - int_adress_0 << endl; //24 bits
cout << "difference in integer = " << ptr6 - ptr0 << endl; //6