Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Question in basic C++

Question in basic C++

Scheduled Pinned Locked Moved C / C++ / MFC
questionc++
18 Posts 9 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    LordsAngel
    wrote on last edited by
    #1

    Assume i have a base class A (which contains a virtual function "test") and its derived class B (implement the virtual function). Now i do :- A* a = new A; memset( a, 0, sizeof( A ) ); a->test(); // here it crashes?? Why? Thanks... Heaven is a girl I know so well She makes me feel good when I feel like hell Heaven is a girl that I've got to have And she makes me feel better when I'm feelin' bad Heaven is a girl that makes dreams come true Oh, no one does it good like heaven do, yeah

    C J M G 4 Replies Last reply
    0
    • L LordsAngel

      Assume i have a base class A (which contains a virtual function "test") and its derived class B (implement the virtual function). Now i do :- A* a = new A; memset( a, 0, sizeof( A ) ); a->test(); // here it crashes?? Why? Thanks... Heaven is a girl I know so well She makes me feel good when I feel like hell Heaven is a girl that I've got to have And she makes me feel better when I'm feelin' bad Heaven is a girl that makes dreams come true Oh, no one does it good like heaven do, yeah

      C Offline
      C Offline
      Cedric Moonen
      wrote on last edited by
      #2

      I'm not totally sure but I think the reason is because once you have a virtual function in your class, you will have a virtual function table added in the class. That is, a table that will redirect the call to a function to the specific function (base or inherit) in function of the type of the object. So, if you 'erase' this table with 0, if you try to call a function within this table, you will try to call a function at memory location 0, which causes a crash.


      Cédric Moonen Software developer
      Charting control

      S E 2 Replies Last reply
      0
      • L LordsAngel

        Assume i have a base class A (which contains a virtual function "test") and its derived class B (implement the virtual function). Now i do :- A* a = new A; memset( a, 0, sizeof( A ) ); a->test(); // here it crashes?? Why? Thanks... Heaven is a girl I know so well She makes me feel good when I feel like hell Heaven is a girl that I've got to have And she makes me feel better when I'm feelin' bad Heaven is a girl that makes dreams come true Oh, no one does it good like heaven do, yeah

        J Offline
        J Offline
        Javagal Srinath
        wrote on last edited by
        #3

        I think main idea behind virtual functions is they r there only so that derived classes could make use of it. If u had written A* a = new B ; ur code would have worked fine. I have not refreshed c++ from last 8 months if I am wrong anybody cancorrect me bye.

        T 1 Reply Last reply
        0
        • J Javagal Srinath

          I think main idea behind virtual functions is they r there only so that derived classes could make use of it. If u had written A* a = new B ; ur code would have worked fine. I have not refreshed c++ from last 8 months if I am wrong anybody cancorrect me bye.

          T Offline
          T Offline
          toxcct
          wrote on last edited by
          #4

          all appologies...

          J 1 Reply Last reply
          0
          • T toxcct

            all appologies...

            J Offline
            J Offline
            Javagal Srinath
            wrote on last edited by
            #5

            I posted before his reply. anyway i will make use of information

            T 1 Reply Last reply
            0
            • J Javagal Srinath

              I posted before his reply. anyway i will make use of information

              T Offline
              T Offline
              toxcct
              wrote on last edited by
              #6

              [Message Deleted]

              J S N 3 Replies Last reply
              0
              • C Cedric Moonen

                I'm not totally sure but I think the reason is because once you have a virtual function in your class, you will have a virtual function table added in the class. That is, a table that will redirect the call to a function to the specific function (base or inherit) in function of the type of the object. So, if you 'erase' this table with 0, if you try to call a function within this table, you will try to call a function at memory location 0, which causes a crash.


                Cédric Moonen Software developer
                Charting control

                S Offline
                S Offline
                Stephen Hewitt
                wrote on last edited by
                #7

                You are correct. This is a classic example of what goes wrong when you mix low level constructs with high level ones without a well developed understanding of how the high-level constructs are implemented. Every class that has virtual functions has a virtual function table; one table is shared between all instances of that class. It contains pointers to virtual functions (or sometimes adjustor thunks to the virtual functions if multiple inheritance is used). When the constructor of a class with virtual functions is called it initializes a pointer in the instance data to point to the class’s vtable: this is the pointer that's being overwritten. In short, if you use simple structs and classes (no virtual functions or multiple inheritance) the layout of the class is what you would naively expect; if you have a struct or class with high-level constructs such as virtual functions or multiple inheritance the layout of the class as a whole will not be so predictable and will contain the book keeping info needed to implement them. Steve

                1 Reply Last reply
                0
                • T toxcct

                  [Message Deleted]

                  J Offline
                  J Offline
                  Javagal Srinath
                  wrote on last edited by
                  #8

                  u r almost right, I was in my own world to be honest I had written my suggestion when nobody had presented reply to the original question, but I failed to press submit. If I was totally wrong I would not have replied. why waste our time unnecessarily on useless point. bye(this time really)

                  1 Reply Last reply
                  0
                  • C Cedric Moonen

                    I'm not totally sure but I think the reason is because once you have a virtual function in your class, you will have a virtual function table added in the class. That is, a table that will redirect the call to a function to the specific function (base or inherit) in function of the type of the object. So, if you 'erase' this table with 0, if you try to call a function within this table, you will try to call a function at memory location 0, which causes a crash.


                    Cédric Moonen Software developer
                    Charting control

                    E Offline
                    E Offline
                    Emilio Garavaglia
                    wrote on last edited by
                    #9

                    Just to be more precise: the v-table is not in the object itself, but somewhere in the system. Its leading address is in the object, and part of the object size, as the virtual base table address (if any). What is erased is not that table itself, but the table address, hence, by invoking a virtual function, you'll try to find the address by seeking the corresponding entry considering the memory "0" to be the table. The crash is not the function invoke, but the attempt to read an invalid memory page to detect wich function to invoke. 2 bugs found. > recompile ... 65534 bugs found. :doh:

                    1 Reply Last reply
                    0
                    • T toxcct

                      [Message Deleted]

                      S Offline
                      S Offline
                      Stephen Hewitt
                      wrote on last edited by
                      #10

                      Sometimes when you start a reply you're the first but you take some time to write it and by the time you send it it's out of date; it has happened to me before today. Steve

                      1 Reply Last reply
                      0
                      • L LordsAngel

                        Assume i have a base class A (which contains a virtual function "test") and its derived class B (implement the virtual function). Now i do :- A* a = new A; memset( a, 0, sizeof( A ) ); a->test(); // here it crashes?? Why? Thanks... Heaven is a girl I know so well She makes me feel good when I feel like hell Heaven is a girl that I've got to have And she makes me feel better when I'm feelin' bad Heaven is a girl that makes dreams come true Oh, no one does it good like heaven do, yeah

                        M Offline
                        M Offline
                        Maximilien
                        wrote on last edited by
                        #11

                        LordsAngel wrote:

                        memset( a, 0, sizeof( A ) );

                        Why the heck are you doing this ?


                        Maximilien Lincourt Your Head A Splode - Strong Bad

                        C 1 Reply Last reply
                        0
                        • M Maximilien

                          LordsAngel wrote:

                          memset( a, 0, sizeof( A ) );

                          Why the heck are you doing this ?


                          Maximilien Lincourt Your Head A Splode - Strong Bad

                          C Offline
                          C Offline
                          Cedric Moonen
                          wrote on last edited by
                          #12

                          A plain C habbit maybe ? In C, for initalizing all data members of a struct, it is quite practical to use such mechanism.


                          Cédric Moonen Software developer
                          Charting control

                          1 Reply Last reply
                          0
                          • T toxcct

                            [Message Deleted]

                            N Offline
                            N Offline
                            Nish Nishant
                            wrote on last edited by
                            #13

                            toxcct wrote:

                            man, either you have a problem in your time management, or you didn't refresh your browser :

                            It's happened to me a few times that I've replied and found someone's replied before me. Regards, Nish


                            Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
                            Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog (New)

                            1 Reply Last reply
                            0
                            • L LordsAngel

                              Assume i have a base class A (which contains a virtual function "test") and its derived class B (implement the virtual function). Now i do :- A* a = new A; memset( a, 0, sizeof( A ) ); a->test(); // here it crashes?? Why? Thanks... Heaven is a girl I know so well She makes me feel good when I feel like hell Heaven is a girl that I've got to have And she makes me feel better when I'm feelin' bad Heaven is a girl that makes dreams come true Oh, no one does it good like heaven do, yeah

                              G Offline
                              G Offline
                              Gary R Wheeler
                              wrote on last edited by
                              #14

                              As a rule in C++, never initialize a struct/class using memset. That's what constructors are for.


                              Software Zen: delete this;

                              Fold With Us![^]

                              S 1 Reply Last reply
                              0
                              • G Gary R Wheeler

                                As a rule in C++, never initialize a struct/class using memset. That's what constructors are for.


                                Software Zen: delete this;

                                Fold With Us![^]

                                S Offline
                                S Offline
                                Stephen Hewitt
                                wrote on last edited by
                                #15

                                There is nothing wrong with initializing a class/struct with memset if you know what you're doing. The basic rule is only use memset on classs/structs which:  - Don't have any virtual functions.  - Don't have any virtual base classes. The above two restrictions are also recursive into the classes members. For example a class itself may not have any virtual functions but some its members may and so it is NOT safe to use memset on it. While you are correct that "that's what constructors are for" there is little doubt that when it is safe to do so it will be more efficient. Most times the efficiency gain will not be worth it but, as always, there will be exceptions. If you really want to use memset but still want to use have virtual functions you can do so like this: struct CMyClass_Data {     CMyClass_Data()     {        memset(this, 0, sizeof(*this)); // Safe as no virtuals.     }       // Put members here... }; class CMyClass : private CMyClass_Data { public:     // Stuff goes here...       virtual VFun1() { /* ... */ }     virtual VFun2() { /* ... */ }     // etc...       // Stuff goes here... } Steve

                                G 1 Reply Last reply
                                0
                                • S Stephen Hewitt

                                  There is nothing wrong with initializing a class/struct with memset if you know what you're doing. The basic rule is only use memset on classs/structs which:  - Don't have any virtual functions.  - Don't have any virtual base classes. The above two restrictions are also recursive into the classes members. For example a class itself may not have any virtual functions but some its members may and so it is NOT safe to use memset on it. While you are correct that "that's what constructors are for" there is little doubt that when it is safe to do so it will be more efficient. Most times the efficiency gain will not be worth it but, as always, there will be exceptions. If you really want to use memset but still want to use have virtual functions you can do so like this: struct CMyClass_Data {     CMyClass_Data()     {        memset(this, 0, sizeof(*this)); // Safe as no virtuals.     }       // Put members here... }; class CMyClass : private CMyClass_Data { public:     // Stuff goes here...       virtual VFun1() { /* ... */ }     virtual VFun2() { /* ... */ }     // etc...       // Stuff goes here... } Steve

                                  G Offline
                                  G Offline
                                  Gary R Wheeler
                                  wrote on last edited by
                                  #16

                                  While what you say is true, it still skates closer to the edge than I prefer. I use memset to initialize simple buffers and other types of POD (plain old data), and that's about it. I do use this construct, however:

                                  struct MyData {
                                  ...
                                  };
                                  MyData data = { 0 };

                                  in preference to memset most of the time. In this case, the compiler will complain if anything in type MyData has a non-trivial constructor, which guarantees at compile time that the operation is safe.


                                  Software Zen: delete this;

                                  Fold With Us![^]

                                  S 1 Reply Last reply
                                  0
                                  • G Gary R Wheeler

                                    While what you say is true, it still skates closer to the edge than I prefer. I use memset to initialize simple buffers and other types of POD (plain old data), and that's about it. I do use this construct, however:

                                    struct MyData {
                                    ...
                                    };
                                    MyData data = { 0 };

                                    in preference to memset most of the time. In this case, the compiler will complain if anything in type MyData has a non-trivial constructor, which guarantees at compile time that the operation is safe.


                                    Software Zen: delete this;

                                    Fold With Us![^]

                                    S Offline
                                    S Offline
                                    Stephen Hewitt
                                    wrote on last edited by
                                    #17

                                    I've got nothing against this technique and use it myself; but it can't achieve exactly the same result as the example I gave. If you want the members that you're ={0}ing to be members of the class with virtual functions this technique can't be used. I reiterate - in general I wouldn't bother with such confusing constructs - but there are exceptions to every rule. Steve

                                    G 1 Reply Last reply
                                    0
                                    • S Stephen Hewitt

                                      I've got nothing against this technique and use it myself; but it can't achieve exactly the same result as the example I gave. If you want the members that you're ={0}ing to be members of the class with virtual functions this technique can't be used. I reiterate - in general I wouldn't bother with such confusing constructs - but there are exceptions to every rule. Steve

                                      G Offline
                                      G Offline
                                      Gary R Wheeler
                                      wrote on last edited by
                                      #18

                                      Stephen Hewitt wrote:

                                      exceptions to every rule

                                      Well, as long as you catch them properly...


                                      Software Zen: delete this;

                                      Fold With Us![^]

                                      1 Reply Last reply
                                      0
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes


                                      • Login

                                      • Don't have an account? Register

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • World
                                      • Users
                                      • Groups