-2

I am trying to invoke the clear() method on a std::map without getting an "Exception thrown: read access violation._Pnode was 0xDDDDDDDD.".

//I have narrowed down the error to this group of code
#include "stdafx.h"
#include <map>
#include <iostream>

class Input
{
    std::map<int, bool> pressedKeys;
    std::map<int, bool> heldKeys;
    std::map<int, bool> releasedKeys;

public:
    void Update()
    {
        heldKeys.clear();
        pressedKeys.clear();
        releasedKeys.clear();
    }
};

class Window
{
private:
    Input * input;
    void Update()
    {
        input->Update();
    }
public:
    Window()
    {
        input = &Input();

        while (true)
        {
            this->Update();
        }
    }
};

int main()
{
    Window w = Window();
}

The exception always happens on "heldKeys.clear();" The debugger in Visual Studio brings me to a page called "xtree." The code that follows is the code around where the exception happens in "xtree:"

void _Erase(_Nodeptr _Rootnode)
    {   // free entire subtree, recursively
    for (_Nodeptr _Pnode = _Rootnode; !_Pnode->_Isnil; _Rootnode = _Pnode) //The error occurs here
        {   // free subtrees, then node
        _Erase(_Pnode->_Right);
        _Pnode = _Pnode->_Left;
        _Alnode& _Al = this->_Getal();
        _Alnode_traits::destroy(_Al, _STD addressof(_Rootnode->_Myval));
        _Node::_Freenode0(_Al, _Rootnode);
        }
    }

I expect no exceptions. I am getting the exception "Exception thrown: read access violation. _Pnode was 0xDDDDDDDD." If any more clarification is needed please comment.

Bilal Shafi
  • 115
  • 2
  • 13
  • 1
    Please post a [mcve]. – PaulMcKenzie Dec 08 '17 at 03:58
  • The problem is not in what you've shown. The problem is not in Microsoft's code unless you're very unlucky. – chris Dec 08 '17 at 03:58
  • Also, this code was typed into the question instead of copied and pasted from your real program. You have `heldkeys` declared in your class, but in your `Update()` function you use `heldKeys` (capital **K**). – PaulMcKenzie Dec 08 '17 at 04:01
  • check your syntax. You declare as `heldkeys` but your Update function uses `heldKeys`, etc. – Suhaib Ahmad Dec 08 '17 at 04:03
  • *I expect no exceptions* -- If someone were to fill in the gaps you left out, it is very easy to get an exception. [See here](https://www.ideone.com/24UcHC) – PaulMcKenzie Dec 08 '17 at 04:08
  • 2
    What is `input = &Input();` supposed to do? Why do you need a pointer? This may give you a clue to what is going wrong: https://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations – Retired Ninja Dec 08 '17 at 05:22
  • I switched from using pointers to references and that fixed my problem, thank you. – Bilal Shafi Dec 08 '17 at 05:27
  • 2
    The point is you're taking the address of a temporary object. Don't do that. It gets destroyed as soon as you hit the `;`. https://ideone.com/3RnDXH – bcrist Dec 08 '17 at 05:29
  • Can you post that as the answer so that I can mark it as correct. – Bilal Shafi Dec 08 '17 at 05:32
  • Possible duplicate of [Lifetime of temporaries](https://stackoverflow.com/questions/4214153/lifetime-of-temporaries) – Retired Ninja Dec 08 '17 at 06:16

1 Answers1

2

Do you have all warnings turned on in your compiler? Really any fairly recent high quality C++ compiler should catch this. E.g. go to http://rextester.com/l/cpp_online_compiler_clang and type in the code, removing the stdafx.h header, which is not needed anyway, and you'll see:

source_file.cpp:31:17: error: taking the address of a temporary object of type 'Input' [-Waddress-of-temporary]
        input = &Input();
                ^~~~~~~~

(Using clang 3.8 as the compiler.)

This proves a much more efficient method for finding a large class of run-of-the-mill programming errors as compared to Stack Overflow. Other classes of errors may involve turning on extra analysis passes or sanitizers such as clang's Address Sanitizer, Memory Sanitizer, or Undefined Behavior Sanitizer.

Zalman Stern
  • 3,161
  • 12
  • 18