Why is object member value changing between 2 getter calls - c++

I am getting unexpected value in second getter call which looks wrong to me, any specific reason for this happening?
#include<iostream>
using namespace std;
class Test {
public:
int &t;
Test (int x):t(x) { }
int getT() { return t; }
};
int main() {
int x = 20;
Test t1(x);
cout << t1.getT() << " ";
cout << t1.getT() << endl;
return 0;
}

The problem here is that your code results in undefined behavior.
The constructor of Test does not take a reference to an int but a copy, and due to int x only being a temporary copy which is not guaranteed to live until your second function call you will end up with undefined behavior.
You would have to change your constructor to the following to make the code work properly:
Test(int& x) : t(x) {}
Now the reference you're working with in Test will be the same x as defined in main

Related

How to access int a declared in main in another function?

#include <iostream>
using namespace std;
void b();
int main() {
int a = 10;
b();
}
void b() {
int a;
cout<<"Int a="<<a;
}
I am looking to print the value of a in the main scope using a function, with my current code, it prints Int a=0. How can I achieve this?
Don't declare an entirely new a inside b().
Pass the a from main to b() and then print that.
For example:
#include <iostream>
void b(int whatever_name_you_want_here);
int main()
{
int a = 10;
b(a);
}
void b(int whatever_name_you_want_here)
{
std::cout << "Int a=" << whatever_name_you_want_here;
}
//Change your code to the following and it will give you the result you're looking for.
On your code there is no way to pass int a on the main to b(); unless b accepts a parameter of the type you want the function to output.
#include<iostream>
void b(int);
int main()
{
int a = 10;
b(a);
}
void b(int a){
std::cout << "int a=" << a;
}
I guess the main problem is not being aware of something very important which is called scope! Scopes are usually opened by { and closed by }
unless you create a global variable, it is only known inside the scope it has been introduced (declared).
you declared the function b in global scope :
void b();
so after this every other function including main is aware of it and can use it.
but you declared the variable a inside the scope of main:
int a = 5;
so only main knows it and can use it.
Please make note that unlike some other programming languages, names are not unique and not every part of the program recognize them in c and c++.
So the part:
void b() {
int a;
does not force the function b to recognize the a which was declared in main function and it is a new a.
so to correct this mistake simply give the value or reference of variable a to function b :
#include <iostream>
void b(int&);
int main() {
int a = 10;
b(a);
}
void b(int& a) {
std::cout << "Int a=" << a << std::endl;
}
please also note that the a as argument of the function b is not the same a in the function main.
The final tip is every argument for functions is known inside that function scope as it was declared inside the function scope!
What you want to achieve requires you to pass a value to a function. Let me give you an example on how to do that.
#include<iostream>
void print_value(int value){
std::cout << "Value is: " << value << '\n';
}
int main(){
int a = 5;
print_value(a);
return 0;
}
The only thing you are missing in your program is the parameter. I won't bother explaining the whole thing over here as there are numerous articles online. Here is a straightforward one.
Refer to this to understand how functions work in C++
Use pass by reference to access a variable which is declared in one function in another.
Refer the below code to understand the use of reference variable,
void swapNums(int &x, int &y) {
int z = x;
x = y;
y = z;
}
int main() {
int firstNum = 10;
int secondNum = 20;
cout << "Before swap: " << "\n";
cout << firstNum << secondNum << "\n";
// Call the function, which will change the values of firstNum and secondNum
swapNums(firstNum, secondNum);
cout << "After swap: " << "\n";
cout << firstNum << secondNum << "\n";
return 0;
}
#include <iostream>
using namespace std;
void displayValue(int number) {
cout<<"Number is = "<<number;
}
int main()
{
int myValue = 77;
displayValue(myValue);
return 0;
}

std::cout changing the variable value

I was coding my function is properly returning a pointer to a reference.
I found that although the function was returning what it was suppose to do, however, std::cout was modifying the results.
Am I doing anything wrong here?
How to rectify this behaviour?
Please refer the following code snippet,
#include "stdafx.h"
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass(int x_):m_Index(x_){}
int m_Index;
};
void myfunction(int *&currentIndex, MyClass obj)
{
currentIndex = &obj.m_Index;
}
int _tmain(int argc, _TCHAR* argv[])
{
MyClass obj(5);
int *Index = NULL;
myfunction(Index, obj);
int curr_Index = *Index;
cout << "Index = " << curr_Index << std::endl; // This works fine.
cout << "Index = " << *Index << std::endl; // This modifies *Index
return 0;
}
void myfunction(int *&currentIndex, MyClass obj)
{
currentIndex = &obj.m_Index;
}
Invokes undefined behavior because obj is only valid for the life of the function call. You keep a pointer to it (or one of it's members) which you use AFTER it has gone out of scope.
You can solve either by pointing to something that doesn't go out of scope (see #songyuanyao's answer). In this case it isn't clear why you need pointers. myfunction could just return the index.
The obj parameter is passed by value, so a copy is made that will be destroyed when the function exits. currentIndex is being set to point to an invalid address, and dereferencing it is undefined behavior. It might work well, or it might not work, anything is possible.
One solution is to make obj be passed by reference instead of by value:
void myfunction(int *&currentIndex, MyClass& obj)
{
currentIndex = &obj.m_Index;
}

about returning a const reference to a temporary argument

I am compiling with g++ 4.8.4 under Ubuntu.
I cannot understand why the code below is working correctly means that prints always on console some output without crashing.
My believe is that the function foo() is assigned a temporary object that will last until the function foo() finishes its execution.
Surely the output argument will point to the same address on the stack where that temporary has been allocated, but I was surprised to find that each call to A::hello() works fine.
I thought that any access to that area of memory should be avoided.
I wanted to double check with 'valgrind' and it is also saying that all is ok. I tried to recompile with -Wstack-protector and nothing.
Do you know why it is happening? Is my believe wrong or it is simply one of those 'undefined' C++ behaviour that is best to avoid?
#include <iostream>
using namespace std;
struct A {
A(): a(10) { cout << "a" << endl; }
~A() {cout << "bye" << endl; }
void hello() const { cout << "hi " << a << endl; }
};
const A& foo(const A& a = A()) {
return a;
}
int main() {
for( int i = 0; i < 10 ; i++) {
const A& a = foo();
a.hello();
}
return 0;
}
Output
'a'
'bye'
'hi 10'
'a'
'bye'
'hi 10'
...
The behaviour is undefined.
Binding a const reference to an anonymous temporary extends the lifetime of that anonymous temporary to the lifetime of that const reference.
But the attempted re-binding of the returned reference to a in foo will not extend the lifetime: lifetime extension is not transitive. So a is a dangling reference in main().

How to initialize the reference member variable of a class?

Consider the following code C++:
#include<iostream>
using namespace std;
class Test {
int &t;
public:
Test (int &x) { t = x; }
int getT() { return t; }
};
int main()
{
int x = 20;
Test t1(x);
cout << t1.getT() << " ";
x = 30;
cout << t1.getT() << endl;
return 0;
}
It is showing the following error while using gcc compiler
est.cpp: In constructor ‘Test::Test(int&)’:
est.cpp:8:5: error: uninitialized reference member ‘Test::t’ [-fpermissive]
Why doesn't the compiler directly call the Constructor?
That is because references can only be initialized in the initializer list. Use
Test (int &x) : t(x) {}
To explain: The reference can only be set once, the place where this happens is the initializer list. After that is done, you can not set the reference, but only assign values to the referenced instance. Your code means, you tried to assign something to a referenced instance but the reference was never initialized, hence it's not referencing any instance of int and you get the error.
My compiler emits this error:
error C2758: 'Test::t' : must be initialized in constructor base/member initializer list
And that's exactly what you must do. References must be initialized in the initializer list:
#include<iostream>
using namespace std;
class Test {
int &t;
public:
Test (int &x) : t(x) { } // <-- initializer list used, empty body now
int getT() { return t; }
};
int main()
{
int x = 20;
Test t1(x);
cout << t1.getT() << " ";
x = 30;
cout << t1.getT() << endl;
return 0;
}
Explanation:
If the reference is not in the initiliazer list, it's next to impossible for the compiler to detect if the reference is initialized. References must be initialized. Imagine this scenario:
Test (int &x, bool b)
{
if( b ) t = x;
}
Now it would be up to the caller of the constructor to decide if valid code was generated. That cannot be. The compiler must make sure the reference is initialized at compile time.

Runtime error when initializing multiple pointers

This is probably just something I don't understand about c++, but why does this code give me a runtime error? If I don't initialize someInt2 or I don't specify that aClass has an int member, I don't get the error.
using namespace std;
class aClass
{
int someint;
public:
aClass()
{
someint=4;
}
};
int bFunc()
{
return 4;
}
aClass aFunc()
{
aClass class1=aClass();
return class1;
}
int main()
{
int * someInt2;
*someInt2=bFunc();
aClass * thisClass;
cout << "Got here" << endl;
*thisClass=aFunc();
cout << "Not here" << endl;
return 0;
}
int * someInt2;
*someInt2=bFunc();
Undefined behaviour. You didn't make someInt2 point anywhere meaningful.
Edit: "Appearing to function correctly" is one of the possible things that "undefined behaviour" can be.
int * someInt2;
is an uninitialised pointer, and yet you are trying to assign a value to what it points to. You need to allocate some memory or simply use a int variable to store the return value of the function.