Changing the value of a pointer passed by reference [duplicate] - c++

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
I have this maybe weird question. I was considering following example where I pass a pointer by reference so if I change the pointer address of the argument the initial pointer should also change the address. And indeed this happens.
However the value of a in the main method will have some random value and not 3 as the q variable inside changePointer whose address we use to change pointer a to.
Is there something stupid oversee or is the whole thing just undefined behaviour.
#include <iostream>
void changePointer(int* &p) {
int q = 3;
std::cout << "Address of q: " << &q << std::endl;
p = &q;
std::cout << "Value of p: " << *p << std::endl;
}
int main() {
int* a = new int(4);
changePointer(a);
std::cout << "Adress of a: " << a << std::endl;
std::cout << "Value of a: " << *a << std::endl;
}

This is undefined behavior because you access a local variable which is already vanished.
Try adding static before int q = 3; and making the variable static so that the variable won't vanish on returning from the function.
Also, please do not cause memory leak by allocating some buffer to a and throwing it away!

q is scoped variable, it gets destroyed when changePointer returns. a then points to freed memory, so it's invalid pointer, and dereferencing it (*a) is Undefined Behavior.
Corrected code:
void changePointer(int* &p) {
int* q = new int(3); // this way q lives until you delete it
std::cout << "Address of q: " << q << std::endl;
delete p; // we don't want unfreeable memory
p = q;
std::cout << "Value of p: " << *p << std::endl;
}
int main() {
int* a = new int(4);
changePointer(a);
std::cout << "Adress of a: " << a << std::endl;
std::cout << "Value of a: " << *a << std::endl;
delete a;
}

q is a local variable inside changePointer, so when changePointer exits the address of q contains garbage.

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;

c++ segfault and pointers confusion (I have the feeling I'm missing something terribly obvious)

I'm a python programmer new to C++. Currently getting a segfault when trying to play around with pointers. Can someone explain this behavior? I suspect there's something significant about cout that I'm not understanding.
#include<iostream>
using namespace std;
int main() {
int var; // declaration
cout << "var declared" << endl;
cout << "var : " << var << endl;
cout << "&var : " << &var << endl;
var = 10; // initialization
cout << "\nvar initialized" << endl;
cout << "var : " << var << endl;
cout << "&var : " << &var << endl;
int* ptr; // declaration
cout << "\nptr declared" << endl;
cout << "ptr : " << ptr << endl;
cout << "*ptr : " << *ptr << endl;
cout << "&ptr : " << &ptr << endl;
ptr = &var; // initialization
cout << "\nptr initialized : " << endl;
cout << "ptr : " << ptr << endl;
cout << "*ptr : " << *ptr << endl;
cout << "&ptr : " << &ptr << endl;
return 0;
}
using this compiler command
g++ --std=c++14 main.cpp -o main_exec;
This code produces the following output
var declared
var : 0
&var : 0x7fff55724478
var initialized
var : 10
&var : 0x7fff55724478
ptr declared
ptr : 0x0
[1] 82727 segmentation fault ./main_exec
This code obviously compiles but produces a segfault at runtime.
Things I've tried
I've tried combinations of commenting out the lines that include *ptr and the lines that include &ptr, short story is some combinations produce no segfault. It seems that I can use *ptr 1 time and not in combination with &ptr
You declared a pointer to an integer, but not initialized or assigned it with any pointer (i.e. to memory address of an integer variable).
int* ptr; // declaration
The line above says, ptr is a pointer (that would point to memory address of an integer variable). In your case it just says it is a pointer, what it does point is not defined.
When you hit this line,
cout << "*ptr : " << *ptr << endl;
Here *ptr means, get the value at address (the address that actually would store the value) and is being pointed by ptr. However ptr points to nothing. So you're trying to access memory in a way that is not permitted which leads to the segmentation fault.
Just remember that pointers are variable that as their values store memory address of another variable.
int *ptr; // would store memory address of an integer type variable.
int a = 5; // would store an integer variable.
ptr = &a; // Here &a gets the address of variable a and stores in *ptr
cout<<*ptr // Here *ptr gets the value of variable whose memory address is pointed to by *ptr.
Edit
To answer the question if int * ptr = new int; is valid.
Yes it will reserve you a memory location and allows you to later store values on that location later, as shown in code below,
int* ptr = new int; // gets memory address and assigns to *ptr
*ptr = 5; // assigns value 5 to the memory being pointed by *ptr
cout<<*ptr; // output 5
However you're supposed to not do this unless you've a particular need.
Variables reserve you memory, and give you a friendly variable name of your choice.
Anything you create with new is not deleted automatically, as suggested in comment section.
Variables, in contrast to this, are deleted automatically when they get out of scope (block, function, loop, etc.)

Does char* have other functions than as a pointer in C++? [duplicate]

This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 3 years ago.
If char* is a pointer (I find its size is always 4 bytes), how do I find its value (the address in hexa or decimal)? I tried &(*p) for char *p. It simply returned the initial string. If it is always 4 bytes, how is it that it can be initialized to long strings but point to the first character? In other words where is the string stored?
Is char* a weird pointer used for purposes other than what a pointer is intended to be?
// an initial pointer (usually its size is 32bit or 64bit, depending on CPU/OS).
// it's value is currently NULL (not pointing anywhere),
// so we can't do very much with this right now.
char* p = nullptr;
// for the sake of sanity, check the value (should be zero)
// we have to convert to intptr_t, otherwise we'd get the string
// value being printed out.
std::cout << "p address = " << intptr_t(p) << std::endl << std::endl;
// lets allocate a few chars to play with
p = new char[10];
// copy in some text value
std::strcpy(p, "Hello");
// and now if we print the address, the text string,
// and the char we are pointing at
std::cout << "p address = " << intptr_t(p) << std::endl;
std::cout << "p string = " << p << std::endl;
std::cout << "p dereferenced = " << *p << std::endl << std::endl;
// for fun, lets increment the pointer by 1
++p;
// this should have made a couple of changes here
std::cout << "p address = " << intptr_t(p) << std::endl;
std::cout << "p string = " << p << std::endl;
std::cout << "p dereferenced = " << *p << std::endl << std::endl;
// decrement again (so we can delete the correct memory allocation!)
--p;
// now free the original allocation
delete [] p;
// if we print again, notice it still has the memory location?
std::cout << "p address = " << intptr_t(p) << std::endl;
// This would be bad to access (we've just deleted the memory)
// So as a precaution, set the pointer back to null
p = nullptr;
// should be back where we started
std::cout << "p address = " << intptr_t(p) << std::endl;

Reassigning C++ reference variables [duplicate]

This question already has answers here:
Can we reassign the reference in C++?
(7 answers)
Closed 7 years ago.
I am trying to understand C++ reference variables. This link seems to indicate that a pointer can be reassigned while a reference should be assigned at initialization. difference between pointer and reference. I have the following code below. I have run it on a debian system. The output is also shown below. The output seems to indicate that reference can be reassigned as well.It would be great if someone could clarify.
#include <iostream>
using namespace std;
int main()
{
int x = 5;
int y = 6;
int *p;
p = &x;
cout << "content of p " << *p << endl;
p = &y;
cout << "content of p " << *p << endl;
*p = 10;
cout << "content of p " << *p << endl;
/*A reference must be assigned at initialization*/
int &r = x;
cout << "content of r " << r << endl;
r = y;
cout << "content of r " << r << endl;
return 0;
}
Output
content of p 5
content of p 6
content of p 10
content of r 5
content of r 10
What you see here is the value being assigned to the variable referenced by the referencing variable.
In other words:
You did not assign new value to the referencing variable. You assigned a new value to the referenced variable.

C++ How would the calling of these functions change if i change the parameter argument from an int* to int [duplicate]

This question already has an answer here:
C++ parameter passing queries (code examples and outputs included)
(1 answer)
Closed 8 years ago.
First of all, i have no idea how to word the title whilst keeping it descriptive if anybody has a better idea feel free to edit.
My question is as follows; I have been given a set of function definitions and calls to these functions which currently operate using an int* as the variable that is being passed in various ways to these functions.
My task is to without changing the function definitions make the program compile and produce the same output but this time use an int over an int*.
Desired output:
Result
first 43
second 43
third 44
fourth 0
fifth 69
This is the code for the when the variable is an int*
void MyIncrementFirst(int* i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int** i) {
*i = new int(0);
}
void MyIncrementFifth(int*& i) {
i = new int(69);
}
int main(){
int* a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " <<*a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
return 0;
}
Now here is what i have so far when changing the type of a to an int, not an int*:
Note: The function definitions are the same as above.
int main(){
int a = 42;
cout << "Result" << endl;
MyIncrementFirst(&a);
cout << "first " <<a << endl;
MyIncrementSecond(a);
cout << "second " <<a << endl;
MyIncrementThird(a);
cout << "third " <<a << endl;
/*
MyIncrementFourth(&a);
cout << "fourth " <<a << endl;
MyIncrementFifth(a);
cout << "fifth " <<a << endl;
*/
return 0;
}
Which prints:
Result
first 43
second 43
third 44
Calls to MyIncrementFourth and MyIncrementFith have been commented because i am not sure how to translate this to handle an int rather than an int*. Any attempts i do would just be fluke rather than knowledge.
Can anybody help me identify how to correctly complete the calls to MyIncrementFourth and MyIncrementFith in order to achieve a correct result.
Thanks,
Chris.
void foo(int a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
While with * it would be like this
void foo(int* a) {
...
}
int main() {
int a = 5;
foo(&a);
return 0;
}
However, this reminds of C.
You could use the & operator, instead of the *, like this:
void foo(int& a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
I assume you know what passing by value and by reference means. If you want a refresh, take a look in my example here.
[EDIT]
Also note that the code in the first block of yours is not OK, since you call new twice, but you never call delete.
Also, about what you are asking, you cannot do it without using an extra pointer. In other words, it can not be done by only having int a in the play.
Example:
int* a_pointer = &a;
MyIncrementFourth(&a_pointer);
cout << "fourth " << a << ", but a_pointer points to " << *a_pointer << endl;
Why the value of a did not change, despite the fact that we set the a_pointer to be equal with the address of a.
Because inside your function, you are calling new and as you know, it will return a pointer to the new allocated memory.
As a result, a_pointer is assigned a new value. Which value? The address of the new allocated memory.
When you use
int a = 42;
instead of
int* a = new int(42);
fourth and fifth function can't be used. The MyIncrementFourth and MyIncrementFifth (counterintuitive names, by the way) pretend to replace the pointer you allocated in the main with another pointer to another area, allocated inside the functions (and there will be a memory leak since you no longer will be able to delete the original a…). But if you stick to int a = 42 instead of int* a = new int(42), your variable is not a pointer, thus those functions have no pointer they can replace.
You can use:
int* ap = &a;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
// It does not change the value a.
You can also use:
int* ap = NULL;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
int* ptr;
MyIncrementFourth(&ptr);
a = *ptr;
delete ptr;
std::cout << "fourth " << a << std::endl;
MyIncrementFifth(ptr);
a = *ptr;
delete ptr;
std::cout << "fifth " << a << std::endl;