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
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Smart pointers

Smart pointers

Scheduled Pinned Locked Moved C / C++ / MFC
csharpc++apacheperformancehelp
31 Posts 8 Posters 0 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.
  • P Pascal Ganaye

    I'd like to speak about pointers, I am trying to stay neutral and thoughtful, please don't transform this thread into a language or belief war. Pointers have several problems. 1 - they can be freed and they then point to garbage 2 - they can be freed twice 3 - sometime the programmer forget to free some memory 4 - probably more... The most common solution these days seem to be using garbage collectors. Garbage collector fix the issues 1,2, 3 above Unfortunately garbage collectors has come with some new problems: - you can't really release memory precisely when you want to - it has to freeze the computer for some time occasionally to count all its blocks - more... There has been a lot of middle way attempts. I know there are many flavour of smart pointers around, I am not claiming I know any of them and this is why I am writing here. Lets imagine we have a language between C++ and C# In this language : - every allocation requires an owner. The root owner would be the application itself. - free is available and work synchronously - when an object get freed, any child object is freed. - when an object is freed any other pointer to it get nullified This would solve our 3 original problems: 1 - they can be freed and they then point to garbage They would point to null 2 - they can be freed twice They would be freed once and then the pointer being null they would not be freed again 3 - sometime the programmer forget to free some memory When the owner is freed, the object is freed I was thinking of implementing those pointers and trying them on a free project like Apache or something like that. But first, I thought I would submit it to all, there is a good chance that it already exists ... Or perhaps the constraint of having an owner is too constraining. It is hard to say until you try on a real project. Having an owner per object could have other advantages in a multi-threading environment. I haven't finished on this but first, does anyone have come across anything like it?

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

    Do create an article when you are done. I don't think modern garbage collector algorithms and implementation suffer a lot of performance degradation, or it would have been well publicized on the interweb. In C#, according to the documentation, there are ways to tell the garbage collection to be less intrusive by setting latency mode (http://msdn.microsoft.com/en-us/library/bb384202.aspx[^]). (mostly from http://stackoverflow.com/questions/147130/why-doesnt-c-have-a-garbage-collector[^] ) In C++ since there is no central garbage collection mechanism approved by the language committee and since the language is and should be platform agnostic, having a consensus on how to do it (design and implementation) it was not added in. But, the C++ language (C++0x, or whatever the revision number is now) offers shared pointers (std::shared_ptr) that can be used as a low level garbage collection mechanism. --- In my experience: - adding garbage collection to an existent code base is nearly impossible and can be very time consuming. - creating new software from scratch with zero memory issues (leaks,overruns ... ) is now easily feasible with the use of modern compilers and debuggers in the hand of good (*) programmers with a good coding process and software practices. (*) I know crappy programmers create crappy code, but with the tools available in VS2010 and VS2011, there's no excuse.

    Watched code never compiles.

    J 1 Reply Last reply
    0
    • P Pascal Ganaye

      I'd like to speak about pointers, I am trying to stay neutral and thoughtful, please don't transform this thread into a language or belief war. Pointers have several problems. 1 - they can be freed and they then point to garbage 2 - they can be freed twice 3 - sometime the programmer forget to free some memory 4 - probably more... The most common solution these days seem to be using garbage collectors. Garbage collector fix the issues 1,2, 3 above Unfortunately garbage collectors has come with some new problems: - you can't really release memory precisely when you want to - it has to freeze the computer for some time occasionally to count all its blocks - more... There has been a lot of middle way attempts. I know there are many flavour of smart pointers around, I am not claiming I know any of them and this is why I am writing here. Lets imagine we have a language between C++ and C# In this language : - every allocation requires an owner. The root owner would be the application itself. - free is available and work synchronously - when an object get freed, any child object is freed. - when an object is freed any other pointer to it get nullified This would solve our 3 original problems: 1 - they can be freed and they then point to garbage They would point to null 2 - they can be freed twice They would be freed once and then the pointer being null they would not be freed again 3 - sometime the programmer forget to free some memory When the owner is freed, the object is freed I was thinking of implementing those pointers and trying them on a free project like Apache or something like that. But first, I thought I would submit it to all, there is a good chance that it already exists ... Or perhaps the constraint of having an owner is too constraining. It is hard to say until you try on a real project. Having an owner per object could have other advantages in a multi-threading environment. I haven't finished on this but first, does anyone have come across anything like it?

      C Offline
      C Offline
      Chris Losinger
      wrote on last edited by
      #4

      Windows (and most modern OS's) will automatically free your allocated-but-unfreed memory when your process exits. the real problem with not freeing memory is that, if you allocate 20MB but don't free it, that's 20MB less that every program running, including your own, can allocate later. by freeing it as soon as you're done, you make it available to be allocated again.

      image processing toolkits | batch image processing

      R 1 Reply Last reply
      0
      • L Lost User

        Smart pointers are OK, for lazy/bad programmers, but not needed otherwise. Which means they are needed a lot. :)

        ============================== Nothing to say.

        J Offline
        J Offline
        JackDingler
        wrote on last edited by
        #5

        LOL. :) There are good reasons to use them on occasion. I've used them when I'm keeping multiple tables of objects in memory, that can be indexed and accessed from different points. I've had this come up in multi-threaded program where multi-threads are processing data at different entry points. In this case there is no clear owner of the object, so there's no clear way to determine when an object is out of scope and can be safely deleted.

        S 1 Reply Last reply
        0
        • P Pascal Ganaye

          I'd like to speak about pointers, I am trying to stay neutral and thoughtful, please don't transform this thread into a language or belief war. Pointers have several problems. 1 - they can be freed and they then point to garbage 2 - they can be freed twice 3 - sometime the programmer forget to free some memory 4 - probably more... The most common solution these days seem to be using garbage collectors. Garbage collector fix the issues 1,2, 3 above Unfortunately garbage collectors has come with some new problems: - you can't really release memory precisely when you want to - it has to freeze the computer for some time occasionally to count all its blocks - more... There has been a lot of middle way attempts. I know there are many flavour of smart pointers around, I am not claiming I know any of them and this is why I am writing here. Lets imagine we have a language between C++ and C# In this language : - every allocation requires an owner. The root owner would be the application itself. - free is available and work synchronously - when an object get freed, any child object is freed. - when an object is freed any other pointer to it get nullified This would solve our 3 original problems: 1 - they can be freed and they then point to garbage They would point to null 2 - they can be freed twice They would be freed once and then the pointer being null they would not be freed again 3 - sometime the programmer forget to free some memory When the owner is freed, the object is freed I was thinking of implementing those pointers and trying them on a free project like Apache or something like that. But first, I thought I would submit it to all, there is a good chance that it already exists ... Or perhaps the constraint of having an owner is too constraining. It is hard to say until you try on a real project. Having an owner per object could have other advantages in a multi-threading environment. I haven't finished on this but first, does anyone have come across anything like it?

          J Offline
          J Offline
          JackDingler
          wrote on last edited by
          #6

          I have a class that has been evolving for some time that satisfies these constraints. It a templatized class, so it is capable of calling the object's destructor. It keeps a static member to a std::map, which serves as the owner of the object, and a location for reference counting. When the 'int' member is decremented to zero, the last class instance out, deletes the object and removes it from the map.

          P 1 Reply Last reply
          0
          • J JackDingler

            I have a class that has been evolving for some time that satisfies these constraints. It a templatized class, so it is capable of calling the object's destructor. It keeps a static member to a std::map, which serves as the owner of the object, and a location for reference counting. When the 'int' member is decremented to zero, the last class instance out, deletes the object and removes it from the map.

            P Offline
            P Offline
            Pascal Ganaye
            wrote on last edited by
            #7

            As I understand it you, count the number of records that point to your object and when it reach zero you free it. I was not clear, I am suggesting this. My idea is you would have a list of all the smart-pointer that point to your object. When the object get deleted (by anyone), all the other pointers that point to it get cleared. So free is really freeing the object but also clear who-ever is still pointing to it.

            J L 2 Replies Last reply
            0
            • P Pascal Ganaye

              As I understand it you, count the number of records that point to your object and when it reach zero you free it. I was not clear, I am suggesting this. My idea is you would have a list of all the smart-pointer that point to your object. When the object get deleted (by anyone), all the other pointers that point to it get cleared. So free is really freeing the object but also clear who-ever is still pointing to it.

              J Offline
              J Offline
              JackDingler
              wrote on last edited by
              #8

              You could do that by keeping a multimap of all of the smart pointers that you create, ordered by the pointer that they reference. Then when you delete to pointer, you could access every smartpointer, and set it's reference pointer to NULL. Then remove all instances of that pointer from your multimap. Give it a try. I think you'll learn a lot by doing this.

              P 1 Reply Last reply
              0
              • J JackDingler

                You could do that by keeping a multimap of all of the smart pointers that you create, ordered by the pointer that they reference. Then when you delete to pointer, you could access every smartpointer, and set it's reference pointer to NULL. Then remove all instances of that pointer from your multimap. Give it a try. I think you'll learn a lot by doing this.

                P Offline
                P Offline
                Pascal Ganaye
                wrote on last edited by
                #9

                I think you got my idea pretty well. So the bad news now. I haven't resolved the problem ptr += something; I assume I'll have to have a size for every object.

                J 1 Reply Last reply
                0
                • P Pascal Ganaye

                  I think you got my idea pretty well. So the bad news now. I haven't resolved the problem ptr += something; I assume I'll have to have a size for every object.

                  J Offline
                  J Offline
                  JackDingler
                  wrote on last edited by
                  #10

                  You might need to derefence your pointer to do pointer math.

                  template class CSPtr
                  {
                  private:
                  T * pData;

                  public:
                  operator T* () { return pData; }

                  public:
                  CSPtr(T * pNewPtr) { /* fill in code */ }
                  // More c;ode...
                  };

                  void func(void)
                  {
                  CSPtr IntPtr = new int[5];

                  int * pInt = (int *) IntPtr;

                  pInt += 2;
                  *pInt = 3;
                  }

                  P 1 Reply Last reply
                  0
                  • J JackDingler

                    You might need to derefence your pointer to do pointer math.

                    template class CSPtr
                    {
                    private:
                    T * pData;

                    public:
                    operator T* () { return pData; }

                    public:
                    CSPtr(T * pNewPtr) { /* fill in code */ }
                    // More c;ode...
                    };

                    void func(void)
                    {
                    CSPtr IntPtr = new int[5];

                    int * pInt = (int *) IntPtr;

                    pInt += 2;
                    *pInt = 3;
                    }

                    P Offline
                    P Offline
                    Pascal Ganaye
                    wrote on last edited by
                    #11

                    There is a problem with my strategy if I allow arithmetic on pointers. If the object is freed the pointer who point 1 byte further is not. I need to do a proof of concept. Anyone know a good 50,000 line of C++ project I could try this on?

                    J 1 Reply Last reply
                    0
                    • P Pascal Ganaye

                      As I understand it you, count the number of records that point to your object and when it reach zero you free it. I was not clear, I am suggesting this. My idea is you would have a list of all the smart-pointer that point to your object. When the object get deleted (by anyone), all the other pointers that point to it get cleared. So free is really freeing the object but also clear who-ever is still pointing to it.

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #12

                      You would need to have a class that manages allocation and manages the pointers pointing to that allocaiton so that when the allocation is freed all the pointers are NULLed. Since the allocations are to be shared, you would want to have some way of refering to those allocations, so that if some code needs an address it calls this class, and if it exists, the existing address is given back, if not, it is created. This class would need to manage access to the address so that only one caller at a time can modify the data. Finally a new class, for the pointers them selves that can track when a pointer is copied so that the new pointer can be added to the list of pointers managed. This is complex though and easilly broken, but could be interesting to try to do.

                      ============================== Nothing to say.

                      1 Reply Last reply
                      0
                      • L Lost User

                        Smart pointers are OK, for lazy/bad programmers, but not needed otherwise. Which means they are needed a lot. :)

                        ============================== Nothing to say.

                        O Offline
                        O Offline
                        Orjan Westin
                        wrote on last edited by
                        #13

                        In a decent design, smart pointers are needed when there's a chance of an exception being thrown.

                        L S 2 Replies Last reply
                        0
                        • P Pascal Ganaye

                          There is a problem with my strategy if I allow arithmetic on pointers. If the object is freed the pointer who point 1 byte further is not. I need to do a proof of concept. Anyone know a good 50,000 line of C++ project I could try this on?

                          J Offline
                          J Offline
                          JackDingler
                          wrote on last edited by
                          #14

                          You could keep a pointer and an offset. Then when doing arithmetic, just change the offset. When you dereference the pointer, add the offset to it.

                          1 Reply Last reply
                          0
                          • M Maximilien

                            Do create an article when you are done. I don't think modern garbage collector algorithms and implementation suffer a lot of performance degradation, or it would have been well publicized on the interweb. In C#, according to the documentation, there are ways to tell the garbage collection to be less intrusive by setting latency mode (http://msdn.microsoft.com/en-us/library/bb384202.aspx[^]). (mostly from http://stackoverflow.com/questions/147130/why-doesnt-c-have-a-garbage-collector[^] ) In C++ since there is no central garbage collection mechanism approved by the language committee and since the language is and should be platform agnostic, having a consensus on how to do it (design and implementation) it was not added in. But, the C++ language (C++0x, or whatever the revision number is now) offers shared pointers (std::shared_ptr) that can be used as a low level garbage collection mechanism. --- In my experience: - adding garbage collection to an existent code base is nearly impossible and can be very time consuming. - creating new software from scratch with zero memory issues (leaks,overruns ... ) is now easily feasible with the use of modern compilers and debuggers in the hand of good (*) programmers with a good coding process and software practices. (*) I know crappy programmers create crappy code, but with the tools available in VS2010 and VS2011, there's no excuse.

                            Watched code never compiles.

                            J Offline
                            J Offline
                            JackDingler
                            wrote on last edited by
                            #15

                            Issues with garbage collection are well documented. For many applications, the advantages of garbage collection outwiegh the disadvantages. Applications can startup faster and see better performance if garbage collection is deferred. The type of application where deferred garbage collection should not be implemented, are apps that require long periods of sustained throughput. In these apps, there is no good time to do the garbage collection, so the requests tend to build towards a criticality. At best the garbage collection will spike processing time while it satisifies requests. At worst, the app can crash because resources can't be made available in a timely manner. In these apps, it's better to coalesce as you free, so the overhead is spread thinly over time, rather than batched when the system is under stress. The last time I had a chance to demonstrate this, I was tasked to datamine a corps internal web servers to populate servers needed to complete an emergency billing cycle. Corporate politics were a major part of the technical considerations. It would've been easier to hit the Oracle SQL Server directly. The internal web servers were Java based, and I was assured that they were tuned by the vendor to maintain high data throughput. I was able to get high throughput out of them for short periods of time, but if I ran sustained requests at about 50,000 record / sec, it didn't take too many minutes before the response time would suddenly slow and the server crash. The solution was to throttle the datamining down to a few thousand records / sec, and to implement cool off intervals so the GC could catch up.

                            1 Reply Last reply
                            0
                            • C Chris Losinger

                              Windows (and most modern OS's) will automatically free your allocated-but-unfreed memory when your process exits. the real problem with not freeing memory is that, if you allocate 20MB but don't free it, that's 20MB less that every program running, including your own, can allocate later. by freeing it as soon as you're done, you make it available to be allocated again.

                              image processing toolkits | batch image processing

                              R Offline
                              R Offline
                              Rick York
                              wrote on last edited by
                              #16

                              That is true if _heapmin() is called periodically. If it is not called the free'd memory is still on the heap of the process that allocated it. _heapmin must be called to release memory back to the OS.

                              C 1 Reply Last reply
                              0
                              • R Rick York

                                That is true if _heapmin() is called periodically. If it is not called the free'd memory is still on the heap of the process that allocated it. _heapmin must be called to release memory back to the OS.

                                C Offline
                                C Offline
                                Chris Losinger
                                wrote on last edited by
                                #17

                                sorry. misread your comment. on most modern desktop operating systems, when a process exits, it's dynamically-allocated memory is freed. _heapmin is useful if you want the OS to get the memory back while your app is running. but i was talking about when it exits.

                                image processing toolkits | batch image processing

                                1 Reply Last reply
                                0
                                • O Orjan Westin

                                  In a decent design, smart pointers are needed when there's a chance of an exception being thrown.

                                  L Offline
                                  L Offline
                                  Lost User
                                  wrote on last edited by
                                  #18

                                  This is a good example of dogma. You dont need smart pointers in exception handled code, since you can easilly deallocate an allocated pointer in any of the exception handling cases.

                                  ============================== Nothing to say.

                                  O 1 Reply Last reply
                                  0
                                  • P Pascal Ganaye

                                    I'd like to speak about pointers, I am trying to stay neutral and thoughtful, please don't transform this thread into a language or belief war. Pointers have several problems. 1 - they can be freed and they then point to garbage 2 - they can be freed twice 3 - sometime the programmer forget to free some memory 4 - probably more... The most common solution these days seem to be using garbage collectors. Garbage collector fix the issues 1,2, 3 above Unfortunately garbage collectors has come with some new problems: - you can't really release memory precisely when you want to - it has to freeze the computer for some time occasionally to count all its blocks - more... There has been a lot of middle way attempts. I know there are many flavour of smart pointers around, I am not claiming I know any of them and this is why I am writing here. Lets imagine we have a language between C++ and C# In this language : - every allocation requires an owner. The root owner would be the application itself. - free is available and work synchronously - when an object get freed, any child object is freed. - when an object is freed any other pointer to it get nullified This would solve our 3 original problems: 1 - they can be freed and they then point to garbage They would point to null 2 - they can be freed twice They would be freed once and then the pointer being null they would not be freed again 3 - sometime the programmer forget to free some memory When the owner is freed, the object is freed I was thinking of implementing those pointers and trying them on a free project like Apache or something like that. But first, I thought I would submit it to all, there is a good chance that it already exists ... Or perhaps the constraint of having an owner is too constraining. It is hard to say until you try on a real project. Having an owner per object could have other advantages in a multi-threading environment. I haven't finished on this but first, does anyone have come across anything like it?

                                    S Offline
                                    S Offline
                                    Stefan_Lang
                                    wrote on last edited by
                                    #19

                                    First, the new C++11 standard does contain smart pointers, and they avoid all of the above problems as well as some that you introduced. Second, C++11 introduced move-semantics, and thereby the concept of passing ownership to another. Your core-premise of a singular ownership directly interferes with that concept. The ANSI commission didn't introduce this on a whim, they had some very good reasons, so why would you want to counter their efforts? Third, this...

                                    Pascal Ganaye wrote:

                                    - when an object is freed any other pointer to it get nullified

                                    is a very bad idea! what are other parts of your application supposed to do when the pointer they rely on suddenly got nullified? How can you guarantee that your whole application isn't left in an undefined state because an operation couldn't be completed? This is an obvious concern in a multi-threaded application, but even single-threaded, it may cause big headaches. Sure, you can create a mutex for a pointer to make sure you can complete your operations, but that also means that the owner may not be able to nullify it's own pointer for an unspecified time. That doesn't quite mix with the conceept of ownership. Fourth, you mention that you know there are smart pointer implementations. Why don't you go have a look at them before implementing a concept of your own? They solve all the problems you listed plus the ones I pointed out above.

                                    P 1 Reply Last reply
                                    0
                                    • J JackDingler

                                      LOL. :) There are good reasons to use them on occasion. I've used them when I'm keeping multiple tables of objects in memory, that can be indexed and accessed from different points. I've had this come up in multi-threaded program where multi-threads are processing data at different entry points. In this case there is no clear owner of the object, so there's no clear way to determine when an object is out of scope and can be safely deleted.

                                      S Offline
                                      S Offline
                                      Stefan_Lang
                                      wrote on last edited by
                                      #20

                                      JackDingler wrote:

                                      In this case there is no clear owner of the object,

                                      Unfortunately, the OP pretty much required a singular ownership. Just one of several reasons why he needs to rethink his premises...

                                      J 1 Reply Last reply
                                      0
                                      • O Orjan Westin

                                        In a decent design, smart pointers are needed when there's a chance of an exception being thrown.

                                        S Offline
                                        S Offline
                                        Stefan_Lang
                                        wrote on last edited by
                                        #21

                                        I disagree - you don't need smart pointers to deal with exceptions. You just initialize all pointers with 0 and in the catch block delete all that are not. Of course, with smart pointers this is easier, but they are not specifically needed.

                                        O 1 Reply Last reply
                                        0
                                        • S Stefan_Lang

                                          First, the new C++11 standard does contain smart pointers, and they avoid all of the above problems as well as some that you introduced. Second, C++11 introduced move-semantics, and thereby the concept of passing ownership to another. Your core-premise of a singular ownership directly interferes with that concept. The ANSI commission didn't introduce this on a whim, they had some very good reasons, so why would you want to counter their efforts? Third, this...

                                          Pascal Ganaye wrote:

                                          - when an object is freed any other pointer to it get nullified

                                          is a very bad idea! what are other parts of your application supposed to do when the pointer they rely on suddenly got nullified? How can you guarantee that your whole application isn't left in an undefined state because an operation couldn't be completed? This is an obvious concern in a multi-threaded application, but even single-threaded, it may cause big headaches. Sure, you can create a mutex for a pointer to make sure you can complete your operations, but that also means that the owner may not be able to nullify it's own pointer for an unspecified time. That doesn't quite mix with the conceept of ownership. Fourth, you mention that you know there are smart pointer implementations. Why don't you go have a look at them before implementing a concept of your own? They solve all the problems you listed plus the ones I pointed out above.

                                          P Offline
                                          P Offline
                                          Pascal Ganaye
                                          wrote on last edited by
                                          #22

                                          Thanks Stefan for you answer. I think I got you on the wrong foot, I don't really suggest that what the C++11 have done is bad. I am only introducing something that is different and I am interested to see where it goes. When I wrote :

                                          Stefan_Lang wrote:when an object is freed any other pointer to it get nullified

                                          I know it is a quite an dangerous concept. In my mind I have this idea, like a little snow ball, I want to roll it and see where it goes.

                                          what are other parts of your application supposed to do when the pointer they rely on suddenly got nullified?

                                          They are not in a worst state than calling an object that has been freed. The . or -> operators can check if the pointer is null or not.

                                          How can you guarantee that your whole application isn't left in an undefined state because an operation couldn't be completed?

                                          I am not sure I follow your thoughts. the free function would basically do:

                                          free(memory)
                                          {
                                          foreach pointer in the entire system who point to memory
                                          *pointer = null
                                          real free(memory);
                                          }

                                          If the pointers got reused later by the rest of the application it is bound to crash anyway as you're not supposed to use a block of memory that have been freed. With this mechanism you can check very deterministically whether the block was freed by simply testing the pointer value. Again I am not here to start a religious war, I am not even saying this is the way to go. I am merely asking what if?

                                          S 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