Collin K Collin K - 3 days ago 6
C++ Question

Using Class Functions with Pointers after reassigning pointer

I can't really think of a good way to phrase this, but I have no idea why, even though it will compile, it crashes upon execution.
I'm trying to invoke a class function, nextTrain() to my class pointer, apt, and it works before I reassign the pointer, however, after running the line

apt = apt->nextTrain()


similar class functions cannot be invoked any longer.

Full Code:

#include <iostream>
#include <string>

using namespace std;

class train {
public:
string cars[100];
int index;
int total;
train(string n) { cars[0] = n; index=0; total=0;}
train(string c[100], int ix, int t) {
for (int i = 0; i < 100; i++) {
cars[i] = c[i];
}
index = ix; total = t;
}
train* nextTrain() {
train t(cars, index, total);
train* ret = &t;
ret->atoix(1);
return ret;
}
train* prevTrain() {
train t(cars, index, total);
train* ret = &t;
ret->atoix(-1);
return ret;
}
void atoix(int val) {
index += val;
}
void add(string name) {
cars[total+1] = name;
total++;
}
string getName() {
return cars[index];
}
};

int main()
{
train a("Engine");
train* apt = &a;
apt->add("Train2");
apt->add("Train3");
cout << apt->nextTrain()->getName() << endl;
apt = apt->nextTrain();
cout << apt->getName() << endl;
cout << apt->nextTrain()->getName() << endl;
cout << apt->prevTrain()->getName() << endl;
cout << apt->getName() << endl;
}

Answer

If we take a closer look at the code in the nextTrain function:

train t(cars, index, total);
train* ret = &t;
...
return ret;

The variable t is a local variable inside the function. When the function returns t will go out of scope and the object will be destructed. However, you return a pointer to this local variable. Once the variable has gone out of scope it doesn't exist anymore, and using this (now invalid) pointer will lead to undefined behavior.

What you should do to solve this problem depends on how you will use it. My suggestion is to not return a pointer from the function, but return an object instance. I.e.

train nextTrain() {
    train t(cars, index, total);
    t.atoix(1);
    return t;
}

Or even

train nextTrain() {
    return train(cars, index+1, total);
}
Comments