CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 43
  1. #16
    Join Date
    Apr 2013
    Posts
    33

    Re: When to use pointers?

    Got it.

    If I understand correctly on the heap means allocating memory dynamically. What does using multiple heaps mean? Sequences of allocated memory with distance between them? (I hope I'm making sense, I'm completely new to memory allocation)

  2. #17
    Join Date
    May 2009
    Posts
    2,413

    Re: When to use pointers?

    Quote Originally Posted by OReubens View Post
    As a general rule concerning pointers and references...
    Use references. Use pointers only when references won't do.
    Just a clarification please. Does this mean you consider it a general rule in C++ to avoid heap allocation of objects? That dynamic allocation always should be used only as a last resort?
    Last edited by nuzzle; April 8th, 2013 at 01:23 AM.

  3. #18
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: When to use pointers?

    No. on the countrary. you should avoid putting large objects on the stack (function local data). As this could cause you to overflow the stack.

    The heap is the right way to go for any non-static non-const objects of any reasonable size.

  4. #19
    Join Date
    May 2009
    Posts
    2,413

    Re: When to use pointers?

    Quote Originally Posted by OReubens View Post
    No. on the countrary. you should avoid putting large objects on the stack (function local data). As this could cause you to overflow the stack.

    The heap is the right way to go for any non-static non-const objects of any reasonable size.
    I don't quite understand your argumentation.

    Do you mean it's the size of an object that determines whether it should be stack or heap allocated? If an object is big enougt to risk overflowing the stack then the heap is fine but if it's sufficiently small then as a general C++ rule the heap should be avoided?

  5. #20
    Join Date
    Oct 2008
    Posts
    1,456

    Re: When to use pointers?

    I think the major source of inefficiency of heap-managed objects is not much the allocation process per-se, but rather that such an approach usually implies a run-time binding of the abstraction entitities. This means poor scalability with respect to the time/space overhead versus the number of "interacting" entities in the design.

    Conversely, value-based abstractions ( eg. abstractions where entities are modeled by regular or semi-regular types, that is types behaving as integer-like objects ) allow compile-time binding enabling potentially optimal space/time performance without sacrificing high-levelness.
    Moreover, the resulting code will look even higher level because every object will be directly visible to the programmer in the code in a natural way, rather than being hidden behind a further level of indirection.

    Of course, I'm not saying that the traditional way of managing OO hyerarchies in C++ should be abandoned ( and I'm very fond of it too ), especially because there are so many other things to consider beyond efficiency before coming to such a conclusion.

    But if one needs a truly scalable solution ( eg. library writers ) then different approches are worth considering IMO.

  6. #21
    Join Date
    May 2009
    Posts
    2,413

    Re: When to use pointers?

    Quote Originally Posted by superbonzo View Post
    This means poor scalability ...
    This is one of the many long-lived myths about OO and virtual functions and it simply isn't true.

    It's because a virtual call resulting from an OO design isn't just a call, it's also a selection. To accomplish the same without a virtual call you need to first select which direct call to make and then perform it. And I can assure you that a compiler generated virtual call is always going to be faster than the if-then-else chain or switch statement or table-lookup or whatever an application programmer might attempt to emulate it.

    Furthermore the difference in modifiability is striking. When you add functionality to a well-designed OO application you do that by adding new classes. Old code isn't touched. This even has a name. It's called the Open/Closed principle. With your procedural approach on the other hand the whole application must be reviewed and every dependency found. An extremely error-prone process.

    And it doesn't stop there. Procedural designs and even template based designs tend to be very monolithic. Everything is connected and brittle. Rather than touching existing code people take the safer bet and start copying code modifying the copies. This leads to code bloat and introduces even more dependencies. What was once only very hard to manage evolves into an untouchable monster over time.

    So don't tell me your approach is "truely scalable". Not in practice and not for systems of some size.

    Bjarne Stroustrup knew what he was up to when he introduced virtual functions. In The Design and Evolution of C++ he writes (p. 49) that with good reason he doubted his ability to teach people how to use them and even more so his ability:

    "to convince people that a virtual function is as efficient in space and time as an ordinary function as typically used".

    And he was right. Today, 20 years later, people appearantly still can't get the head around this fact.
    Last edited by nuzzle; April 19th, 2013 at 05:32 AM.

  7. #22
    Join Date
    Oct 2008
    Posts
    1,456

    Re: When to use pointers?

    Quote Originally Posted by nuzzle View Post
    This is one of the many long-lived myths about OO and virtual functions and it simply isn't true.

    It's because a virtual call resulting from an OO design isn't just a call, it's also a selection.
    tell me, where did I say that the reason of non-scalability is the virtual call ??? the point is exactly to avoid that "selection" in the first place, unless it's truly required to happen at runtime. I just said that traditional OOP promotes runtime binding of entities at run time even when not necessary or intended by the programmer.

    Quote Originally Posted by nuzzle View Post
    even template based designs tend to be very monolithic. Everything is connected and brittle.
    is the STL "connected", "brittle" and "monolothic" ???

  8. #23
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: When to use pointers?

    Quote Originally Posted by nuzzle View Post
    I don't quite understand your argumentation.

    Do you mean it's the size of an object that determines whether it should be stack or heap allocated? If an object is big enougt to risk overflowing the stack then the heap is fine but if it's sufficiently small then as a general C++ rule the heap should be avoided?
    "sort of" ALthough you're conclusion is the other way around. it's not that the heap should be avoided, but stack should be prefered.

    From a performance P.O.V. function local data is prefered. Other than global data, this incurs the smallest amount of overhead.
    if you allocate an object, there is an overhead for allocating the object, and eventually deallocating the object. There is a non-zero performance cost associated with (de)allocation. There is also a slight increase in code for the allocation and deallocation. And there may or may not be an increase in code size (with a slight performance loss) each time you use the allocated object because of the pointer indirection.
    That allocation cost matters is even visible in the STL where std::string is optimised to havign an internal buffer rather than an allocated one for small sizes.


    For most functions, the overhead won't matter much because the function itself won't be called enough times to make a noticable difference. But in a critical function, the allocation/deallocation can make a big difference. This can be particularly true in a multithreaded application where a thread may have to wait on other threads to complete their allocation/deallocation request. For obvious reasons, the heap access needs to be synchronised afterall.

    Other than that there is also the ease of code writing.
    if you have a function and this function needs an int... would you just write an int ? or allocate an int* ? What about if you needed a std::string do you just use the string or allocate an std::string* ?
    unless you "really had to" for some reason, no sane programmer will do an allocation for this.

    so yes, the general rule would be "use function local data for everything". And you would except that rule for big objects that would overflow the stack (or significantly contribute to it), and for objects that need to be dynamic and thus mandate allocation.
    Last edited by OReubens; April 19th, 2013 at 09:09 AM.

  9. #24
    Join Date
    May 2009
    Posts
    2,413

    Re: When to use pointers?

    Quote Originally Posted by superbonzo View Post
    tell me, where did I say that the reason of non-scalability is the virtual call ???
    You said runtime binding causes non-scalability and in common C++ lingo "runtime binding" refers to late binding of virtual function names. If you deviate from that usage you'll have to be clear about it.

    So what do you mean by late binding? And while you're at it, how does it cause non-scalability?

    the point is exactly to avoid that "selection" in the first place, unless it's truly required to happen at runtime. I just said that traditional OOP promotes runtime binding of entities at run time even when not necessary or intended by the programmer.
    You're just relaying urban myths about OO but I'll go into that when you've clarified what you mean by late binding and how this relates to the non-scalability you claim it causes.

    is the STL "connected", "brittle" and "monolothic" ???
    I don't see how the STL standard has anything to do with this discussion.

    Or are you referring to a specific STL implementation? Well, even if you located one of excellent quality that wouldn't prove anything about template based systems in general. As I said, they tend to be very monolithic with the negative consequences I mentioned.

  10. #25
    Join Date
    Oct 2008
    Posts
    1,456

    Re: When to use pointers?

    Quote Originally Posted by nuzzle View Post
    I don't see how the STL standard has anything to do with this discussion. Or are you referring to a specific STL implementation?
    maybe it's a terminology problem, but to me, "connected", "brittle" and "monolithic" are properties related to a (library) design, not its implementation, sorry if you meant something else. The STL is an example of a good template based library design that is neither "connected" nor "brittle" nor "monolithic". And there are many other existing field-proven examples.

    Quote Originally Posted by nuzzle View Post
    You said runtime binding causes non-scalability and in common C++ lingo "runtime binding" refers to late binding of virtual function names.
    yes, indeed "the cost of late binding of virtual function names ( in the usual C++ OOP practice )" is not the same of the "cost of a virtual call". The latter is just the difference in space-time overhead of a virtual call VS a simple function call; the former includes the latter plus any cost implied by the use of late-binding VS static-binding of function names in a typical OOP design. Maybe, it's again just a matter of terminology so sorry if I haven't been clear on this.

    in order to avoid further confusion, let's agree on what "traditional C++ OOP" is ( from now on, C++OOP ). Obviously, there's no such a universally defined thing so you'll forgive me if I make a hopefully innocuous semplification, by saying that a "C++OOP" design is a set of non-copy/move-constructible/non-copy/move-assignable classes related by public inheritance and respecting the liskov principle. Moreover, let's assume all instances of such classes are accessed/managed via (smart)pointers. The classes are the "entities" of the design, "relations" between entities are modeled by the classes interfaces ( both member and free ).

    let's also agree on what a "template based design" ( from now on, C++TB ) is: again simplifying, let's say it's a set of "concepts" ( constraints on types and type templates ), a set of "models" ( types/type templates modeling some concept ) and a set of "algorithms" acting on concepts ( ordinary functions and metafunctions, including concept checking/model generation facilities ). The "entities" of the design are the concepts and the models, "relations" between entities are modeled by the set of algorithms and the types interfaces ( both member and free ).

    Finally, by "non-scalability" I'm referring to the space-time overhead asymptotics of a C++OOP design compared to an equivalent C++TB design, with respect to its number of entities and relations. Two such designs are considered equivalent if one can map entities and relations of each other in a one-to-one fashion.

    Now, if we reasonably agree on the problem statement, we can start arguing ..., do we agree ?

    PS: Note that I never claimed that everybody should care about such a scalability issue. Indeed, I fully agree with your Bjarne's quote about "typical" efficiency. I'm specifically thinking at library writers whose abstractions are expected to efficiently work for a wide use case scenarios ... clearly, such programmers represents a possibly small fraction of all programmers. Their work is nonetheless important, though.
    Last edited by superbonzo; April 22nd, 2013 at 04:32 AM.

  11. #26
    Join Date
    May 2009
    Posts
    2,413

    Re: When to use pointers?

    Quote Originally Posted by OReubens View Post
    it's not that the heap should be avoided, but stack should be prefered.
    Okay, I get your point. And I agree, but only when the choise is devoid of any design considerations. Then the principle simply is the good old Occam's razor; to strive for the simplest solution, and the stack definately is simpler than the heap. But the performance gap has constantly been narrowing. And old truths may quickly become outdated. For example what you say about the heap and multithreading is likely to be outdated post C++ 11.

    In my view a more important principle is what Donald Knuth famously expressed as: Premature optimization is the root of all evil! If you feel the heap is the better design choise then go for it. In a broader context it may even be the more efficient one.
    Last edited by nuzzle; April 22nd, 2013 at 06:17 AM.

  12. #27
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: When to use pointers?

    Quote Originally Posted by nuzzle View Post
    But the performance gap has constantly been narrowing. And old truths may quickly become outdated. For example what you say about the heap and multithreading is likely to be outdated post C++ 11.
    There will ALWAYS be a non-zero cost associated with allocation/deallocation. Multithreading may make the effects more dramatic due to synchronisation needs.

    I'm not sure how or even if at all C++11 can make any change to this. how would a compiler know that
    Code:
    std::string* foo()
    {
       return new std::string("foo");   // Which allocator ?
    }
    automatically needs to use a different heap depending on the thread this was called from? And if it can decide... this then has an "undefined" allocator. so what happens with the type ? is this a plain std:string or is if different from the "same" std::string made from another thread. Right now, the explicit allocator means they're different types.

    ok, so maybe it uses thread local storage to do this, but a compiler cannot guarantee this will even work. What about deallocation. Who's the guarantee that it'll be deallocated on the same thread ? C++11 cannot remove the need for a heap to need synchronisation (which you CAN do for extra performance with a custom allocator if you know it won't ever be used cross-thread).

    maybe it could decide on a heap per allocation/new as from what thread initiated it, but I.m.o. that would probably be more of a problem as a general approach than an actual benefit. Maybe there is a good reason for not wanting separate threads, so how do you override the default behaviour ?

    So IMHO, I doubt any "automatic" system for allocators for multithreading is going to happen. Although I can see them adding custom thread-based allocators STL alongside the current single one, but you'll have to explicitely define your classes to use them.
    Then again... i might be wrong

  13. #28
    Join Date
    Oct 2008
    Posts
    1,456

    Re: When to use pointers?

    Quote Originally Posted by OReubens View Post
    I'm not sure how or even if at all C++11 can make any change to this.
    regarding the hypothetical thread-friendly heap I agree with you, it seems possible only as a compromise rendering some use cases sub-optimal ( which is against the C++ philosophy, IMHO ).

    That said, c++11 does provide many enhancements to allocators, most notably: allocator_traits easing the creation of custom allocator, full support to stateful allocators, the scoped allocator adaptor allowing "nested" allocations in containers and finally the template alias syntactic sugar thanks to which the allocator can be specified just once in a single scope. So, writing and using "plug-and-play" default allocator replacement has never been easier

  14. #29
    Join Date
    May 2009
    Posts
    2,413

    Re: When to use pointers?

    Quote Originally Posted by superbonzo View Post
    maybe it's a terminology problem, but to me, "connected", "brittle" and "monolithic" are properties related to a (library) design, not its implementation, sorry if you meant something else.
    Well, then you've learned something new because these words are commonly used about designs in general, but less so in the context of design of standards. In fact I don't think I've ever a heard a standard being called connected, brittle or monolithic, even though I suppose standards can be all of that.

    do we agree
    I think you're making a mountain out of a molehill. It all boils down to how two different kinds of polymorphism are supported and commonly implemented in C++, namely subtype and parametric. You claim parametric scales better than subtype but you haven't explained how?

    My position is that they scale identically. Even though names are bound at different times the actual polymorphic selection takes place at runtime in both cases, possibly through different but still equivalent mechanisms.
    Last edited by nuzzle; April 24th, 2013 at 04:28 AM.

  15. #30
    Join Date
    May 2009
    Posts
    2,413

    Re: When to use pointers?

    Quote Originally Posted by OReubens View Post
    There will ALWAYS be a non-zero cost associated with allocation/deallocation. Multithreading may make the effects more dramatic due to synchronisation needs.
    There is no special heap synchronization necessary if the default heap internally manages one heap per thread. Then threads aren't competing for a single heap, they all have their own.
    Last edited by nuzzle; April 24th, 2013 at 04:38 AM.

Page 2 of 3 FirstFirst 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured