0

I'm allocating dynamic memory in my class as a private: variable

Then in the constructor I'm trying to initialize the array.

public
Display(int Width, int Height) {
    nScreenHeight = Height;
    nScreenWidth = Width;
    DWORD dwBytesWritten = 0;
    for (int i = 0; i < (nScreenWidth*nScreenHeight); i++) screen[i] = L'';
    SetConsoleActiveScreenBuffer(hConsole);
}

private:
    int nScreenWidth;
    int nScreenHeight;
    wchar_t *screen = new wchar_t[nScreenWidth*nScreenHeight];

If I try run the program an Exception Unhanded in thrown.

Unhandled exception thrown: write access violation. this->screen was 0x2096112.

While trying to initialize the buffer screen with L' '

6
  • 1
    wchar_t *screen = new wchar_t[nScreenWidth*nScreenHeight]; nScreenHeight and nScreenWidth are not initailized when this executes. Initialize screen in your constructor. Commented May 28, 2019 at 17:35
  • 1
    wchar_t *screen = new wchar_t[nScreenWidth*nScreenHeight]; doesn't do what you think it does. I wonder if this even compiles. Put screen = new wchar_t[nScreenWidth*nScreenHeight] to your constructor initializer list at least. Commented May 28, 2019 at 17:36
  • 1
    Unrelated, out of curiosity, what does L'' actually evaluate as? I'm surprised that even compiles. Commented May 28, 2019 at 17:40
  • It is type LPCWSTR simply trying to clear the buffer with empty spaces. But indeed I was messing up what is where. Commented May 28, 2019 at 17:42
  • @WhozCraig I know, right? I was expecting L"", (a pointer to a null-terminated wchar_t string) not L'' . L'' should result in a compiler error: error: empty character constant. Commented May 28, 2019 at 18:05

1 Answer 1

3

Memebers are initialized in the order they appear in the class declaration before the body of the constructor is executed. So what happens is:

  • nScreenWidth is default initialized (see here)
  • nScreenHeight is default initialized
  • screen is initialized with new wchar_t[nScreenWidth*nScreenHeight]
  • only now the constructor runs and you assign values to nScreenWidth and nScreenHeight

Use the initializer list for all members to avoid confusion:

Display(int Width, int Height) : 
   nScreenWidth(Width), nScreenHeight(Height), screen(new wchar_t[nScreenWidth*nScreenHeight])
{
    DWORD dwBytesWritten = 0;
    for (int i = 0; i < (nScreenWidth*nScreenHeight); i++) screen[i] = L'';
    SetConsoleActiveScreenBuffer(hConsole);
}

Even better would be to use a std::vector<wchar_t>, the constructor would be

Display(int Width, int Height) : 
       nScreenWidth(Width), nScreenHeight(Height), screen(Width*Height)
{
    ...

and instead of bothering about the rule of three/five you can rely on the rule of zero.

Sign up to request clarification or add additional context in comments.

3 Comments

@WhozCraig cannot believe I missed a chance to promote std::vector ;)
@ formerlyknownas_463035818 as you mentioned that members are initialized in order they appear in class and after that constructor runs so could not understand why exception occurred ?
@Kapil oh i didnt mention it explicitly. Look at my bulletpoints again, when you initialize the vector you initialize it with 0 size, because only later you assign the passed size to the members. Then when you try to access elements of the array you go out of bounds

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.