15

我有一个带有静态成员的类,它是一个像这样的指针:

动画.h

class Animation
{
public:
    Animation();
    static QString *m;

};

动画.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”将进入一个参数,所以我被卡住了。

谢谢你的帮助!

4

3 回答 3

15

我敢打赌它不会在那条线上崩溃,而是在之后。

问题是您正在获取位于自动内存中的变量的地址,然后可能会尝试访问它。该变量x将在其范围结束时被销毁,但仍将指向该内存(超出范围Animation::m后您不再拥有的内存)。x这会导致未定义的行为

就像下面这样是非法的:

int* x = NULL;
{
   int k = 3;
   x = &k;
}
*x = 4;

解决方法分配给值,而不是指针(前提是它之前被分配给一个有效的QString*):

QString x("Testing");
*(Animation::m) = x;
于 2012-05-16T14:13:42.200 回答
2

第二种方法有什么问题?

x它崩溃是因为您很可能在创建范围之外访问它。

一旦控件退出创建它们的范围,自动变量就会自动销毁{ },因此超出范围的是指向不存在数据的指针。访问此数据会导致未定义行为和崩溃。

怎么办?

您应该动态分配内存,然后将字符串复制到动态分配的指针,以便您能够在任何地方访问它。这样,除非明确delete编辑,否则字符串将保持有效。

于 2012-05-16T14:14:04.830 回答
1

我敢打赌,当您使用Animation::mafterx已被销毁(可能超出范围)时,您的程序会崩溃。

如果您想使用 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.

于 2012-05-16T14:18:51.977 回答