locked
how to use exceptions? RRS feed

  • Question

  • In this code

    #include <string>
    #include <memory> //shared_ptr
    
    namespace abc {
     class MyClass {
     protected:
      //! All purpose exception
      std::shared_ptr<abc::Exception> apex;
      void Init(){ apex.reset(new abc::Exception()); }
     public:
      MyClass(){Init();}
      virtual ~MyClass() {}
      void Test(){ apex->setException(/*some params*/); throw apex; }
     }; //MyClass
    } // abc
    
    int main(){
     auto ex = make_shared<abc::Exception>();
     try{
      auto m_class = make_shared<abc::MyClass>();
      m_class->Test();
     }catch(std::shared_ptr<abc::Exception>& e){
      e.Display();
     }
    }
    
    I get this error

    Error
    Unhandled exception at 0x00007FF7BA7D1744 in Project1.exe: 0xC0000005: Access violation reading location 0x0000000000000000.  

    However, I was expecting my abc::Exception class to "catch" the exception.

    What am I doing wrong?

    Tuesday, June 23, 2015 8:52 AM

Answers

  • I thought that the amount of space in the heap was bigger than the stack. And as far as I understand pointers are stored in the heap, that is one of the benefit of using pointers, if not the only one. Also, passing by address is way cheaper than passing by value, and my exception class will be passed from one place to another in the program, since it contains all the necessary information that would clearly describe the anomaly that created it; pointers store that information and passing the address of the information is better, way better, than passing all the data. However, we must be careful, since some programmers used to forget to free them, that is virtually impossible now. smart pointers handle this 'freeing' of the memory. However, in my research, either the information about smart pointers is too sketchy or the engineering of them is really bad, since using smart pointers is so much more complicated than the... dumb pointers. It certainly was much easier for me to create a pointer and then pass a reference to a calling method, or in this case, the catching method.

    Pointer, not being so easy to use, but comments like the ones I received fro Igor that are as empty full as a bucket of... well too many decent folks around here to use that anal-o-gee, but it suffices to say, not very useful help. Sarcasm is really not a means of helping those who are in need and burlesque comments are for people who suffer from child abuse. And, yes, thank you, but no thank you, http://stackoverflow.com/ is full of people like yourself. If I was a moderator here I would find a way to limit your abusive behaviour towards those who come here looking for help.

    David Wilkinson, did you considered that what you told me before was as substantial as a Campbell's Soup and that that is the reason I am looking for better food at another place. Your reply being, "Oh, but it works for me" was not very substantial; and than have the audacity to say, "as I told you before". Your reply was useless, it did not help me at all, that is why I am here asking the very same question, I just did not have the ruddiness to tell you, but you don't have the wits to ascertain my disdain.

    To the moderator, there is a tangible, but invisible force that seeks to bring down Microsoft, perhaps you should be aware of its soldiers in this forum.

    I am discontinuing this question, please don't replay.

     
    • Marked as answer by del noble Monday, July 6, 2015 11:44 PM
    • Edited by del noble Monday, July 6, 2015 11:48 PM
    Monday, July 6, 2015 11:44 PM

All replies

  • You did not show us your abc::Exception class.

    I was able to get your code to run correctly by replacing abc::Exception by std::exception (and making other appropriate changes).

    Why do you feel it is necessary to wrap your exception in a shared_ptr? Normally you would just throw abc::Exception and catch by const reference.


    David Wilkinson | Visual C++ MVP


    • Edited by davewilk Tuesday, June 23, 2015 3:04 PM clarification
    Tuesday, June 23, 2015 9:33 AM
  • On 6/23/2015 4:52 AM, del noble wrote:

      }catch(std::shared_ptr<abc::Exception>& e){
       e.Display();

    This can't possibly compile - std::shared_ptr doesn't have a method named Display. Hence, the code you are running is different from the code you've shown. Prepare an MCVE ( http://stackoverflow.com/help/mcve ).


    Igor Tandetnik
    Tuesday, June 23, 2015 2:59 PM
  • By default, I load all objects on the heap.  The advance of C++11 to the use of smart pointers makes it safer and easier to use pointers and the memory management of them. abc::Exception is just a class or object that, deriving from std::exception, it explains things better at debugging time; instead of just saying "There is a RunTime Error", it actually explain where and why it occurred, i.e.

    - The name of the file where the exception was found
    - The line number in the file
    - A quick explanation detailing the reasons of the exception.

    That's all.

    Now, where my doubts lie is whether throw[ing] an object of the class template std::shared_ptr<> is better than std::shared_ptr::get()

    I know that catch(std::shared_ptr<abc::Exception>& e) is NOT catching the thrown exception, but neither is catch(abc::Exception& e), when I throw the exception using the member-function get().

    As you can see, my problem is not that the program is not working properly, my problem is that I don't know how to use smart pointers, when these are used with exceptions. Thus any help regarding this issue would be very much appreciated.

    Wednesday, June 24, 2015 5:44 AM
  • By default, I load all objects on the heap.  The advance of C++11 to the use of smart pointers makes it safer and easier to use pointers and the memory management of them

    // ...

    Now, where my doubts lie is whether throw[ing] an object of the class template std::shared_ptr<> is better than std::shared_ptr::get()

    I know that catch(std::shared_ptr<abc::Exception>& e) is NOT catching the thrown exception, but neither is catch(abc::Exception& e), when I throw the exception using the member-function get().

    As you can see, my problem is not that the program is not working properly, my problem is that I don't know how to use smart pointers, when these are used with exceptions. Thus any help regarding this issue would be very much appreciated.

    As I told you in my previous post, your usage of shared_ptr with exceptions works for me (in VS2008) if I replace abc::Exception by std::exception.

    It would be easier to help you if you supplied complete compilable code. As Igor pointed out, even the code you did supply could not possibly compile.


    David Wilkinson | Visual C++ MVP

    Wednesday, June 24, 2015 10:39 AM
  • On 6/24/2015 1:44 AM, del noble wrote:

    By default, I load all objects on the heap.

    Why, if you don't mind me asking? What advantage do you believe this gives you? Normally, one would want to create as fewer objects on the heap as possible.

    Now, where my doubts lie is whether throw[ing] an object of the class template std::shared_ptr<> is better than std::shared_ptr::get()

    Yes, unless you like to see your programs crashing. In your example, by the time catch clause is reached, m_class is destroyed, and so is the MyClass object it used to point to, and so is its apex member. abc::Exception object that apex used to point to is only kept alive by the shared_ptr that's a copy of apex, made by throw expression. If instead you throw a raw pointer, abc::Exception will be destroyed together with everything else, and that raw pointer will be dangling by the time you catch it.

    Anyway, exceptions are designed to be thrown by value and caught by const reference. With all due respect, I feel your adventures in throwing by shared_ptr are misguided.

    I know that catch(std::shared_abc::Exception>& e) is NOT catching the thrown exception, but neither is catch(abc::Exception& e), when I throw the exception using the member-function get().

    Well, of course. If you throw a raw pointer, you need to catch a raw pointer, as in catch (abc::Exception* e) . However, as I said, this will only get your program to compile, but not run. Any attempt to actually use `e` would exhibit undefined behavior, as `e` would be a dangling pointer.

    As you can see, my problem is not that the program is not working properly, my problem is that I don't know how to use smart pointers, when these are used with exceptions.

    It's best to not use smart pointers with exceptions in the first place.


    Igor Tandetnik
    • Marked as answer by Shu 2017 Thursday, July 2, 2015 8:59 AM
    • Unmarked as answer by Shu 2017 Tuesday, July 7, 2015 1:02 AM
    Wednesday, June 24, 2015 12:14 PM
  • I thought that the amount of space in the heap was bigger than the stack. And as far as I understand pointers are stored in the heap, that is one of the benefit of using pointers, if not the only one. Also, passing by address is way cheaper than passing by value, and my exception class will be passed from one place to another in the program, since it contains all the necessary information that would clearly describe the anomaly that created it; pointers store that information and passing the address of the information is better, way better, than passing all the data. However, we must be careful, since some programmers used to forget to free them, that is virtually impossible now. smart pointers handle this 'freeing' of the memory. However, in my research, either the information about smart pointers is too sketchy or the engineering of them is really bad, since using smart pointers is so much more complicated than the... dumb pointers. It certainly was much easier for me to create a pointer and then pass a reference to a calling method, or in this case, the catching method.

    Pointer, not being so easy to use, but comments like the ones I received fro Igor that are as empty full as a bucket of... well too many decent folks around here to use that anal-o-gee, but it suffices to say, not very useful help. Sarcasm is really not a means of helping those who are in need and burlesque comments are for people who suffer from child abuse. And, yes, thank you, but no thank you, http://stackoverflow.com/ is full of people like yourself. If I was a moderator here I would find a way to limit your abusive behaviour towards those who come here looking for help.

    David Wilkinson, did you considered that what you told me before was as substantial as a Campbell's Soup and that that is the reason I am looking for better food at another place. Your reply being, "Oh, but it works for me" was not very substantial; and than have the audacity to say, "as I told you before". Your reply was useless, it did not help me at all, that is why I am here asking the very same question, I just did not have the ruddiness to tell you, but you don't have the wits to ascertain my disdain.

    To the moderator, there is a tangible, but invisible force that seeks to bring down Microsoft, perhaps you should be aware of its soldiers in this forum.

    I am discontinuing this question, please don't replay.

     
    • Marked as answer by del noble Monday, July 6, 2015 11:44 PM
    • Edited by del noble Monday, July 6, 2015 11:48 PM
    Monday, July 6, 2015 11:44 PM