初始化指针时写访问冲突

Write access violation when initializing pointer

我在尝试动态创建数组时遇到写访问冲突,似乎存储指针的内存地址无效。

Header:

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;

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

如有任何帮助,我们将不胜感激。

精简版

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


长版

在您未发布的代码编年史中的某个地方有一些 class、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() 成员中的内存分配不是问题。相反, 问题是指向 non-existent/invalid 对象成员的结果指针的存储,并且是尝试使用无效指针或引用的直接结果实际上 不是 对象的对象。

最好的证据是您在最后张贴的项目中泄露了这一点,试图打印成员本身的地址。你是这样说的:

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

似乎打印 null,有时打印 4,等等

根据 C++ 标准,class 类型成员(例如您的 m_Font)驻留在可寻址的 space 中,位于包含对象基址的某个可能填充的位置。在第一个成员之间甚至之后可以有填充,但 从不 在第一个成员之前。因此,如果 m_FontFoo class 的第一个成员,那么下面的所有地址都是等价的:

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

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

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