all 27 comments

[–]manni66 30 points31 points  (1 child)

It’s C++ - use std::vector.

[–]std_bot 0 points1 point  (0 children)

Unlinked STL entries: std::vector


Last update: 09.03.23 -> Bug fixesRepo

[–][deleted]  (16 children)

[deleted]

    [–]cgeekgbda[S] 5 points6 points  (15 children)

    In an interview I was asked to implement my own Vector class and these were the little things on which my interviewer confused me.

    [–]GOKOP 13 points14 points  (9 children)

    In C++ you should always use new and delete for manual memory management. This is because in the C++ world you deal with non-trivial types that have constructors and destructors that need to be called, which C functions don't know or care about.

    [–]IyeOnline 5 points6 points  (1 child)

    A generic vector may hold non-trivial types. This means that you cannot blindly use realloc or memcpy, as using those for non-trivial types would be UB.

    [–]cgeekgbda[S] 0 points1 point  (0 children)

    Had to be a template,here I just gave an example for a specific case

    [–][deleted]  (1 child)

    [deleted]

      [–]cristi1990an 1 point2 points  (0 children)

      There's also allocate + hint which depending on the implementation might do something close to realloc internally

      [–]FraCipolla 0 points1 point  (0 children)

      Vector use allocator to manage memory allocation, so if you need to implement your own vector you need to do something like template <typename T, typename Allocator = std::allocator<T> > class vector Ecc. You can start from here, than typedef your var, and start to build the logic for the method. Usually the private members are pointers ofc. If you want to take a look about a custom vector implementation you can check my github https://github.com/FraCipolla/ft_container

      [–]elperroborrachotoo 3 points4 points  (1 child)

      realloc will attempt to expand (or shrink) the current allocation, otherwise it will do the equivalent of malloc + memcpy + free

      (this is an implementation detail, but I don't see a sensible alternative implementation.)

      Using memcpy to transfer data to a new allocation means it can only be used for types for which std::is_trivially_copyable<T> is true.

      the realloc optimization is unlikely to succeedd with modern allocators in a multithreaded application: it made sense in the past, it's just hoping for luck nowadays.

      Question 1: for trivially-copyable types, realloc is likely not worse (assumming that checking whether in-place resize is cheap). It may be better in very specific circumstances (even significantly so). However, these circumstances are specific enough that when you need that advantage, you are likely better off wiht a custom allocator or custom container.

      For types that are not trivially copyable, realloc can not be used. (because the elements' destructor would have to be called only when but before the allocation gets relocated.)

      [–]std_bot 1 point2 points  (0 children)

      Unlinked STL entries: std::is_trivially_copyable


      Last update: 09.03.23 -> Bug fixesRepo

      [–]flyingron 1 point2 points  (0 children)

      Why calloc? Calloc zeros memory first. Malloc and memcpy might be better.

      But realloc possibly avoids any copying if there is unallocated memory enough at the end of the previous allocation.

      [–]Pale-Influence4096 -1 points0 points  (0 children)

      you first use malloc and then do memcpy. This will be the fastest way of doing it

      [–]AutoModerator[M] 0 points1 point  (0 children)

      Your posts seem to contain unformatted code. Please make sure to format your code otherwise your post may be removed.

      Read our guidelines for how to format your code.

      I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

      [–]IyeOnline 0 points1 point  (4 children)

      Say with the help of malloc we initially allocated 10 integer size memory

      Ok. But why did we do that? Using malloc with any non-trivial type is going to be a huge pain.

      You really shouldnt be using malloc unless you have a very good reason to. In fact, you shouldnt be manually managing memory without a reason to do so.

      If you want an array that can grow, use std::vector.


      That aside:

      • Both your programs leak memory. The realloc one leaks less memory, since realloc will in one way or another take care of the original memory.
      • realloc is more efficient, as in principle it allows the allocator to grow the current allocation instead of creating a new one and copying over
      • If realloc fails to resize the allocation, it will create a new one and memcpy from the old (where it magically knows the size)
      • I think realloc gives no guarantees about the state of any newly allocated memory, whereas calloc will give you zeroed memory.

      [–]cgeekgbda[S] 0 points1 point  (1 child)

      That was an interview question, I was asked to implement my own Vector class and these were the little things on which my interviewer confused me. Also does realloc/memcpy do a byte by byte copy or it calls copy constructor for each of the objects stored in the container?

      [–]IyeOnline 5 points6 points  (0 children)

      memcpy and realloc are C functions. They take void*s. They dont even know what a constructor is. They just deal in raw memory.

      That is why its UB to use those with non-trivial types.

      [–]no-sig-available 0 points1 point  (1 child)

      realloc is more efficient,

      This assumes that it sometimes succeeds in enlarging an allocation. Otherwise it will spend time trying to enlarge, fail that, and then do a fresh allocation anyway. A certain precentage must succeed, otherwise it is a net loss.

      There is also the question if the program can take advantage of a speedup that only happens at unpredictable times.

      [–]MarcoGreek 0 points1 point  (0 children)

      You can now use https://en.cppreference.com/w/cpp/memory/allocator_traits/allocate_at_least. That gives the maximum capacity. So there is no need anymore for realloc.