初始化指针时写入访问冲突

时间:2018-05-03 20:25:00

标签: c++ directx-11 access-violation nullptr

我在尝试动态创建数组时遇到写入访问冲突,看起来就像存储指针的内存地址无效。

部首:

struct FontType
{
    float left;
    float right;
    float size;
}

FontType* m_Font = nullptr;

来源:

m_Font = new FontType[60];

错误消息显示为:

Exception thrown: write access violation.
this was nullptr.

运行

std::cout << &m_Font << std::endl;

返回不同的地址,例如00000000或00000004,我认为这是问题,但我不知道如何解决这个问题。

任何帮助都将不胜感激,谢谢。

1 个答案:

答案 0 :(得分:2)

短版

您通过包含 m_Font成员的指针或引用访问的对象无效。

长版

在您未发布的代码的历史记录中的某个地方是某个类Foo,它有一个成员FontType *m_Font;在某个地方你有这个:

struct FontType
{
    float left;
    float right;
    float size;
};

struct Foo
{
    FontType *m_Font;

    Foo() : m_Font(nullptr)
    {
    }

    void bar()
    {
        m_Font = new FontType();
    }
};

尽管使用了裸指针(不好主意),问题还是来自(仍然)未发布的代码中的 else ,如下所示:

int main()
{
    Foo *pf = nullptr;

    pf->bar(); // BAD - dereferencing an invalid pointer
}

如果您认为nullptr是上述问题,请允许我向您保证这同样无效:

int main()
{
    Foo *pf;

    pf->bar(); // BAD - dereferencing an indeterminate pointer
}

简而言之,bar()成员内的内存分配不是问题所在。相反,它是将结果指针存储到 问题的不存在/无效对象的成员,并且是尝试使用无效指针或引用的直接结果实际上不是对象的对象。

最好的证据就是你在最后发布的项目中泄露,试图打印成员本身的地址。你这样说:

std::cout << &m_Font << std::endl;

似乎打印为空,有时为4,等等。

根据C ++标准,类类型成员(例如您的m_Font)位于包含对象基础的某个可能填充位置的可寻址空间中。在第一个成员之前,甚至可以在从不之间存在填充。因此,如果m_FontFoo类的第一个成员,则以下所有地址都是等效的:

&m_Font == &this->m_Font == this

根据第一个成员之前不能填充的要求,并且包含对象的地址等于其第一个成员的地址。

所有这一切意味着this必须等同于nullptr,在执行std::cout << &m_Font的代码的上下文中并为输出生成空指针,假设{{ 1}}是第一个成员(实际上它必须是如果null确实是打印输出)。