I am fairly new to C++ and have been coding Java for over 4 years. The memory management of C++ is new to me and I want to make sure I understand it correctly.
My problem seems to be that a variable is passed to a function, stored in a pointer, and said variable goes out of scope.
Is it correct that when Function ends, ms goes out of scope and any subsequent access to sp will be to bad memory? Is it also correct that if I pass s by reference and store the value instead of the pointer that when s goes out of scope, sp will still be valid?
Now my problem is that Struct has virtual methods and it is the base struct for structs that need to be stored for saving to a file later, therefore, I need to store s as a pointer to avoid slicing off of the subclass members. I was planning on adding an enum to keep track of the type. This seems kind of convoluted though and I am wondering if there is a better way.
How do I go about solving this? Will I need to have some management class that stores references to every available type before they go out of scope?
Your naming scheme is strange. What's with all the leading m's? Sometimes that scheme is used for member variables, but not for everything!
Your spacing is also terrible. Indentation should be 4 spaces, and consistent.
The way you've written it, msp is never valid. You are saving the address of the ctor's parameter, which is essentially a local variable. It goes out of scope at the end of the ctor. To fix it you can either pass in the address, or accept it as a reference.
I tried passing by reference and the pointer still ends up becoming corrupted.
In my program o is in main(), o2 is in func() like you have, and I need to access o2 in o after func() is called. Keep in mind that Object is a virtual class.
Is it correct that when mFunction ends, ms goes out of scope and any subsequent access to msp will be to bad memory?
Yes.
Is it also correct that if I pass ms by reference and store the value instead of the pointer that when ms goes out of scope, msp will still be valid?
If you're making a copy, yes it will still be valid. But to avoid confusion, show a specific example if you're not sure if it's valid or not.
Show a complete, but minimal program that reproduces your issues.
If you're coming from Java, note that C++ has different practices in various ways. If you explain the actual problem you're trying to solve, someone might be able to tell you a more C++-esque solution.
#include <iostream>
class Base {
public:
virtualvoid print() const = 0;
};
class Object : public Base {
public:
void print() const override {
std::cout << "hello\n";
};
};
class Object2 {
Base* po;
public:
Object2() {};
void set(Base& o){
po = &o;
};
void print() const {
po->print();
};
};
class Object3 {
public:
Object3() : o2() {};
Object2 o2;
};
void func1(Object3& o3){
Object o;
o3.o2.set(o);
}
void func2(Object3& o3) {
o3.o2.print();
}
int main() {
Object3 o3;
func1(o3);
func2(o3);
}
To do this, I think I would need to add o to a data structure with the proper type to avoid the pointer location from becoming invalid. I also think I would need to add an enum to Object2 and cast the po before calling print(). Is this really the best way to go about it? This means having to create a container (std::map?) for each type in o3 (or a management class) and tagging o2 with a key that it would supply o3 during a callback in it's destructor.
Perhaps my Java background is putting blinders on me and there is a better way to handle this?