Search code examples
c++directx-11access-violationnullptr

Write access violation when initializing pointer


I am getting a write access violation when attempting to dynamically create an array, it seems as like the memory address at which the pointer is stored is invalid.

Header:

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

FontType* m_Font = nullptr;

Source:

m_Font = new FontType[60];

The error message reads:

Exception thrown: write access violation.
this was nullptr.

Running

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

returns different addresses such as 00000000 or 00000004 which I believe is the problem but I don't know how to fix this.

Any help would be appreciated, thanks.


Solution

  • Short Version

    The object you're accessing via pointer or reference which contains the m_Font member is invalid.


    Long Version

    Somewhere in the annals of your unposted code is some class, Foo, that has a member FontType *m_Font; Somewhere you have this:

    struct FontType
    {
        float left;
        float right;
        float size;
    };
    
    struct Foo
    {
        FontType *m_Font;
    
        Foo() : m_Font(nullptr)
        {
        }
    
        void bar()
        {
            m_Font = new FontType();
        }
    };
    

    The use of naked pointers notwithstanding (bad idea), the problem stems from somewhere else in your (still) unposted code, that looks like this:

    int main()
    {
        Foo *pf = nullptr;
    
        pf->bar(); // BAD - dereferencing an invalid pointer
    }
    

    If you think the nullptr is the problem above, let me assure you this is equally invalid:

    int main()
    {
        Foo *pf;
    
        pf->bar(); // BAD - dereferencing an indeterminate pointer
    }
    

    In short, the memory allocation within the bar() member isn't the problem. Rather, it's the storage of the resulting pointer to a member of a non-existent/invalid object that is the problem, and is a direct result of attempting to use an invalid pointer or reference to an object that actually isn't an object.

    The best evidence of this is divulged in the item you posted near the end, trying to print the address of the member itself. You said this:

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

    seemed to print null, sometimes 4, etc.

    According to the C++ standard, class type members (such as your m_Font) reside in addressable space at some potentially padded location from the base of the containing object. There can be padding between, and even after, but never before the first member. Therefore, if m_Font is the first member of the Foo class, then all of the addresses below are equivalent:

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

    per the requirement that the first member cannot have padding before it and the address of the containing object is equivalent to the address of its first member.

    What all of that means is that this must be equivalent to nullptr, in the context of the code that is performing std::cout << &m_Font and producing a null pointer for output, assuming m_Font is the first member (in fact it must be if null is indeed the printed output).