std::cout changing the variable value - c++

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;
}

Related

Pass a point into a thread and have it modified

I need to keep reference of an object passed into a thread. The way the environment is setup I must keep application specific drawing in the same thread it was initiated. So I tuck away app init code in a thread and then get a reference to a custom component I'm interested in.
This isn't working. The app loads and shows up fine but the pointer to the app in the main thread is always null. Even if I use std::shared_ptr or std::ref. Doesn't seem to matter what I do, the pointer is always null.
#include <thread>
#include <iostream>
class SomeClass {
public:
int value;
SomeClass() { value = 0; }
};
void ExecuteThread(SomeClass* c) {
c = new SomeClass();
c->value = 555;
}
int main(int argc, char** argv) {
SomeClass* c = nullptr;
// std::ref(c) doesn't work
// Have also tried passing std::shared_ptr<SomeClass>
std::thread t1 = std::thread(&ExecuteThread, c);
t1.join();
std::cout << "c: " << c << "\n";
std::cout << "c->value: " << c->value << "\n";
return 0;
}
Just so that people do not get confused by incorrect self-answer, I am providing my own, correct answer.
The prime issue with OPs code is the fact that passing pointer by value copies the pointer, and any modification to it will not affect the original. Threads do not change this fact, and do add nothing to it. In particular, the code can be illustrated as
void change(int* k) {
k = nullptr;
}
int i;
k = &i;
change(k);
// k here is still the same as before calling `change`
If one wants to change passed pointer, it should be passed as a reference: void change(int*& k).
Having threads here changes things slightly. Since there is no way to pass something to a std::thread constructor by reference, std::ref needs to be used. The function signature should still accept pointer by reference, and std::ref should be used where thread is created:
auto t = std::thread(change, std::ref(k))
std::thread secretly makes copies of everything you pass as an argument including pointer data. This is incredibly misleading. The only way around that is to pass an address to a pointer and have the thread copy that. Then in your thread's task, deference to a pointer.
#include <thread>
#include <iostream>
class SomeClass {
public:
int value;
SomeClass() { value = 0; }
};
void ExecuteThread(SomeClass** c) {
*c = new SomeClass();
*c->value = 555;
}
int main(int argc, char** argv) {
SomeClass* c = nullptr;
std::thread t1 = std::thread(&ExecuteThread, &c);
t1.join();
std::cout << "c: " << c << "\n";
std::cout << "c->value: " << c->value << "\n";
return 0;
}

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().

const-correctness for this and member functions

assuming that I have a generic class A
class A {
...
int a; // a member
void foo() const{...} // a member function qualified as const
...
};
this implies that if I declare an instance of A like A k; and then I call k.foo(); the this pointer that is acting on/inside that call to foo is something of type const A * const .
Now I would like to know why the code in this blog post works, especially about why this doesn't apply to global variables.
My explanation is about an hidden operation about pointer aliasing, like the this pointer being copied implicitly and during this copy the result is not const anymore ( for some reason ... ) but it's still a this pointer meaning that is a pointer to the same instance.
My question is about: what really const does if it's applied after the declaration of an interface for a member function ? Do you have a specific answer for the linked blog post ?
code from the blog
#include <iostream>
class counter {
public:
int i;
counter();
int inspect() const;
void increment();
};
counter sigma_inspect; // sigma_inspect is global
counter::counter() { i = 0; }
int counter::inspect() const {
sigma_inspect.increment();
return i;
}
void counter::increment() {
++i;
return;
}
int main(void) {
counter a;
std::cout << a.inspect() << "\n";
std::cout << sigma_inspect.inspect() << "\n";
std::cout << sigma_inspect.inspect() << "\n";
return 0;
}
The call in the blog post is using sigma_inspect which is non-const and it is calling a non-const method on it instead of calling said method through the const this pointer. So what? The author seems to expect magic instead of the obvious of what he wrote. It's like having
T* t = ...;
const T* ct = t;
t->foo(); // foo() is not const, but hey,
// I also have a const pointer now (ct),
// so why can I still use this???
Generally, if someone calls C++ stupid it tells you more about the author instead of the language :)

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.

Access a vector like an array[] inside a function

I want to access the vector in the "manipulatevector" function below the same way as i access an array with vector[i] and not vector->at(i) in the code below. I have tried to pass the vector directly, and not a pointer as can be done with arrays. But this seem to corrupt the program. Any ideas how this can be achieved? Im new to using the std library, as i mostly have experience from C.
#include <vector>
#include <iostream>
#define vectorsize 5
struct st_test {
int ii;
float dd;
};
void manipulatevector(std::vector<struct st_test> *test) {
test->resize(vectorsize);
for(int i=0;i<vectorsize;i++) {
test->at(i).dd = i*0.4f;
test->at(i).ii = i;
}
}
void manipulatearray(struct st_test test[vectorsize]) {
for(int i=0;i<vectorsize;i++) {
test[i].dd = i*0.4f;
test[i].ii = i;
}
}
void main() {
std::vector<struct st_test> test1;
manipulatevector(&test1);
struct st_test test2[vectorsize];
manipulatearray(test2);
std::cout << "Vector" << std::endl;
for(int i=0;i<vectorsize;i++) {
std::cout << test1.at(i).dd << std::endl;
}
std::cout << "Array" << std::endl;
for(int i=0;i<vectorsize;i++) {
std::cout << test2[i].dd << std::endl;
}
}
Have you tried passing the vector as a reference?
void manipulatevector(std::vector<struct st_test> &test) {
test.resize(vectorsize);
for(int i=0;i<vectorsize;i++) {
test[i].dd = i*0.4f;
test[i].ii = i;
}
}
and
std::vector<struct st_test> test1;
manipulatevector(test1);
You can simply use (*test)[i] instead of test->at(i).
This is not actually the same behavior (at vs operator[]), but you are probably already aware of that.
Pass it as a reference instead of a pointer.
void manipulatevector(std::vector<struct st_test> &test) {
You then use . instead of ->, and things like the overloaded [] operator are usable.
Change the signature of void manipulatevector(std::vector<struct st_test> *test) to void manipulatevector(std::vector<struct st_test>& test). Then you can use the operator[] on the vector.
You can pass the vector by reference and use the [] operator:
void manipulatevector(std::vector<struct st_test>& test) {
test.resize(vectorsize);
for(int i=0;i<vectorsize;i++) {
test[i].dd = i*0.4f;
test[i].ii = i;
}
}
When you passed the vector directly, I presume you passed it by value:
void manipulatevector(std::vector<struct st_test> test) {
which meant any changes made inside manipulatevector() would not be seen by the caller. This would mean:
for(int i=0;i<vectorsize;i++) {
std::cout << test1.at(i).dd << std::endl;
}
would throw a std::out_of_range error, from test.at(i), as test1 would not have vectorsize elements, but zero elements. As there is no exception handling in main() this would have caused the program to crash.
There are different options here. You can pass the vector by reference, which is the simplest and cleaner in code:
void function( std::vector<type>& v )
Now, in some shops the style guide requires that if you are going to modify an argument you pass it by pointer as that makes it explicit at the place of call. In that case there are different options to call operator[]:
void function( std::vector<type> *v ){
(*v)[0] = .... // dereference first
v->operator[](0) = .... // explicitly cal the operator
std::vector<type>& vr =*v;
vr[0] = .... // create reference and use that
The first two are equivalent, with the first being arguably easier to read. The second is equivalent to the first one in that it dereferences the pointer and then accesses the operator, but you are explicitly giving a name to the reference, so it can be reused in the function without having to dereference in all uses. While this technically creates an extra variable, the compiler will most probably optimize the reference away.