我有一个带有静态成员的类,它是一个像这样的指针:
animation.h
class Animation
{
public:
Animation();
static QString *m;
};
animation.cpp
#include "animation.h"
QString* Animation::m = 0;
Animation::Animation()
{
}
当我尝试从另一个类初始化那个'm'指针时:
Animation::m = new QString("testing");
有效。
但是当我这样做的时候:
QString x("Testing");
Animation::m = &x;
程序崩溃。
第二种方法有什么问题?
此外,我希望将该静态指针设置为私有,以便我可以为其创建静态getter和setter函数。设置者应该使用第二种方法,因为'x'将出现在参数中,所以我卡住了。
感谢您的帮助!
答案 0 :(得分:13)
我打赌它并没有在那条线上崩溃,而是之后。
问题是您正在获取位于自动内存中的变量的地址,并可能在之后尝试访问它。变量x
将在其范围结束时被销毁,但Animation::m
仍将指向该内存(x
超出范围后您不再拥有的内存)。这会导致未定义的行为。
就像以下情况一样:
int* x = NULL;
{
int k = 3;
x = &k;
}
*x = 4;
解决方法分配给值,而不是指针(前提是它先前已分配给有效的QString*
):
QString x("Testing");
*(Animation::m) = x;
答案 1 :(得分:2)
第二种方法出了什么问题?
崩溃是因为您最有可能在创建x
的范围之外访问它。
一旦控件退出创建它们的范围{
}
,自动变量就会自动销毁。因此,除了范围之外,指针指向不存在的数据。访问此数据会导致未定义的行为和崩溃。
如何解决?
您应该动态分配内存,然后将字符串复制到动态分配的指针,以便您可以在任何地方访问它。这样字符串保持有效,除非明确地delete
编辑。
答案 2 :(得分:1)
我敢打赌,在Animation::m
被销毁之后使用x
时,你的程序会崩溃(可能超出范围)。
如果要使用setter分配给Animation::m
,则需要将参数作为指针或引用传递:
class Animation
{
public:
Animation();
void set_m( QString* ptr) {
m = ptr;
}
void set_m( QString& ref) {
m = &ref;
}
private:
static QString *m;
};
但是,当您尝试使用m
时,您仍然需要确保m
点仍然存在。