By accident I found that with a polymorphic type using dynamic_cast back to the derived class will throw a 'bad cast' error if the pointer is no longer valid. Is this undefined behavior or could this be a way to check for valid pointers without using smart pointers? I'm not really against using smart pointers as they serve a real need, but I dislike the syntax. I don't have anything against templated types but I find smart pointers to bloat the code and I'm not a fan of macro's to try and avoid that bloat. I wish C++ included something in the language syntax itself vs using the template feature but with this question I'm more concerned about what is happening below and if this is a valid and defined way to checking for valid pointers as this gives an exception every time from my tests.#include <string>#include <map>using namespace std;class Base{public:    virtual ~Base(){}};class Derived : public Base{public:    virtual ~Derived(){}};class Storage{private:    map<string, Base*> storage;public:    void AddItem(string name, Base* base)    {        if (storage.find(name) == storage.end())        {            storage[name] = base;        }    }    template <class T>    T& FindItem(string name)    {        if (storage.find(name) != storage.end())        {            Base* item = storage[name];            return dynamic_cast<T&>(*item);        }        throw;    }};int main(){    Storage store;    // force 'd' to go out of scope for our test    {        Derived d;        store.AddItem(test, &d);    }    // this will throw a bad cast exception    Derived& test = store.FindItem<Derived>(test);    return 0;}
In C++ is casting to find bad pointers undefined behavior?
c++
dynamic-cast needs to deference the pointer to find the proper offset it should be at, dereferencing an invalid pointer is undefined behavior, one thing you might see:class Derived2 : public Base{public:    virtual ~Derived2(){}};int main(){    Storage store;    {        Derived d;        store.AddItem(test, &d);    }    {        Derived2 d2;        Derived2& test = store.FindItem<Derived2>(test);//might not throw an exception        //test might refer to d2    }    return 0;}Messing about with a void* buffer and placement new and destroy will let me insert anything in there.Just go with smart pointers and learn to appreciate them for the blessing that they are.