I have a class with a static member that's a pointer like so :
animation.h
class Animation
{
public:
Animation();
static QString *m;
};
animation.cpp
#include "animation.h"
QString* Animation::m = 0;
Animation::Animation()
{
}
When I try to initialize that 'm' pointer from another class like so :
Animation::m = new QString("testing");
It works.
But when I do it this way :
QString x("Testing");
Animation::m = &x;
The program crashes.
What is wrong with this second method ?
Also I would like to have that static pointer as private so I can make static getter and setter functions to it. The setter should use the second method as the 'x' will come in a parameter so I'm stuck.
Thanks for any help!
I bet it's not crashing on that line, but afterwards.
The problem is that you're taking the address of a variable located in automatic memory, and probably try to access it afterwards. The variable x
will be destroyed when it's scope ends, but Animation::m
will still point to that memory (memory you no longer own after x
went out of scope). This results in undefined behavior.
Just like the following would be illegal:
int* x = NULL;
{
int k = 3;
x = &k;
}
*x = 4;
Workaround assign to the value, not the pointer (provided it was previously assigned to a valid QString*
):
QString x("Testing");
*(Animation::m) = x;
What is wrong with this second method ?
It crashes because you most likely access it beyond the scope in which x
was created.
Automatic variables are automatically destroyed once the control exits the scope {
}
in which they were created, So beyond the scope what you have is an pointer pointing to data that does not exist. Accessing this data causes an Undefined Behavior and a crash.
How to go about it?
You should dynamically allocate memory and then copy the string to the dynamically allocated pointer so that you are able to access it everywhere. This way the string remains valid unless and untill explicitly delete
ed.
I'll bet that your program crashes when you use Animation::m
after x
has been destroyed (probably by going out of scope).
If you want to use a setter to assign to Animation::m
, you'll need to pass in the argument as a pointer or by reference:
class Animation
{
public:
Animation();
void set_m( QString* ptr) {
m = ptr;
}
void set_m( QString& ref) {
m = &ref;
}
private:
static QString *m;
};
However, you'll still need to make sure that whatever m
points still is still alive when you try to use m
.