Weak Pointers in C++ (std::weak_ptr)

Поділитися
Вставка
  • Опубліковано 5 вер 2024

КОМЕНТАРІ • 206

  • @TheCherno
    @TheCherno  2 місяці тому +14

    What do you guys think? How often do you see weak pointers? 👇
    Also don’t forget you can try everything Brilliant has to offer-free-for a full 30 days, visit brilliant.org/TheCherno . You’ll also get 20% off an annual premium subscription.

    • @hassanalmasri3935
      @hassanalmasri3935 2 місяці тому

      I just see shared pointers actually.
      To me there is a time for each type ❤️

    • @kevinabate6056
      @kevinabate6056 2 місяці тому

      I tend to have a preference for encapsulation, so that I know exactly what's going on in memory both in terms of code size and memory allocation. Sometimes the documentation, even for standard libraries, let's admit it, can be a bit obtuse and I often run into the problem where I had to do things the hard way anyway just to understand what the standard is doing, at all. I'm the kinda guy that would be very fastidious about what goes on in the stack, even though I run a system that has an obscene amount of memory for the application set that I run, because it affords you some additional freedom in terms of what kind of optimizations you can implement as far as data access within code that "technically" works just fine, but might have an issue with readability.

    • @n1ghtyunso
      @n1ghtyunso 2 місяці тому

      I just had a case at work one week ago where changing some shared_ptr to weak_ptr would have solved the immediate problem. Unfortunately, the whole design was flawed and the real solution was to get rid of shared_ptr completely.
      In my opinion, real shared ownership is quite rare and most of the time shared_ptr usage is hinting at a design flaw.

    • @RPG_Guy-fx8ns
      @RPG_Guy-fx8ns 2 місяці тому

      I think with Data Oriented Design, you don't need pointers.
      use ECS. unique indexes. don't use objects. manage the lifetime of your entities by moving their traits into or out of various arrays of that trait.
      Relational databases don't need pointers. neither do any data structure, it can always be done with integer indexes replacing pointers.

    • @AtomicAndi
      @AtomicAndi 2 місяці тому

      Never used it

  • @perivesta
    @perivesta 2 місяці тому +114

    15:25 removing the observer from the vector while iterating invalidates the current iterator and would not work. You'd need to use the iterator returned from erase() instead of the range-for-loop here.

    • @codures
      @codures 2 місяці тому +11

      Unfortunately, it will work, but not quite as expected!

    • @NotherPleb
      @NotherPleb 2 місяці тому +7

      True, nice catch. Even experienced programmers make these silly mistakes and I'm sad no warning is provided by the compiler or static code analysis...

    • @perivesta
      @perivesta 2 місяці тому +3

      It really does seem like there should be at least a clang-tidy check for stuff like this, but I guess it can be hard to detect when it's several functions deep and across TU borders.

    • @zanagi
      @zanagi 2 місяці тому

      Lol i got told this by chatgpt alot

    • @MyCiaoatutti
      @MyCiaoatutti 2 місяці тому +1

      Yep, and this is true for all programming languages that support list/vector iteration (I think). Need to pay attention to element removal during iteration. Replacing iterator with the return value of erase() is the way to go.

  • @Dimkar3000
    @Dimkar3000 2 місяці тому +22

    A good case for weak pointer is back referencing. If a class owns another but you want to able to go from the child to the parent, then you can use weak pointers. Something like child1->parent->func(). You know your parent is alive and this way you avoid cyclic dependecies.

    • @AtomicAndi
      @AtomicAndi 2 місяці тому

      I think it's also the only good case

  • @zami001001
    @zami001001 2 місяці тому +12

    Writing your own smart pointers is probably one of the best learning exercises for C++ in my opinion. Obviously not everyone is going to have a use case for a custom smart pointer implementation, but it teaches you a lot about templating, object lifetime and operator overloading, just to scratch the surface.

    • @dougpark1025
      @dougpark1025 2 місяці тому +3

      This is a excellent observation. I have done this more than once. The ability to write your own smart pointer should be a fundamental skill that one learns when learning C++. Knowing how to do this teaches you RAII, which is useful for many things besides memory management. It also forces you the better understand the overhead of managing memory. If you can write a smart pointer for memory, you can do the same for managing any other resource as well.

    • @harleyspeedthrust4013
      @harleyspeedthrust4013 Місяць тому +1

      Agreed. Writing any sort of RAII class, like a custom data structure, is also a good way to learn about data ownership and lifetimes. Some of my most instructive moments in C++ were when I realized that a strange bug was only present because I hadn't followed the rule of three (or five). It also helps to learn rust, which forces you to think about data ownership

  • @vineilan
    @vineilan 2 місяці тому +15

    Huge thanks for your C++ series. I learn new stuff every time I watch it.

  • @InverseTachyonPulse
    @InverseTachyonPulse 2 місяці тому +36

    6:58 "He's dead, Jim." Loved it 😁

    • @mgoonga
      @mgoonga 2 місяці тому +2

      "Who's pointer is this?" "It's Zed's" "And where is Zed?" "Zed is dead, baby!"

  • @garrethutchington1663
    @garrethutchington1663 2 місяці тому +8

    15:14 Removing an element from a vector while you're currently iterating over said vector will invalidate the reference to the current element in the for loop.
    In this case, you're holding the current element by value, so it's not a problem. But if you're holding it as a reference, weird juju happens.

    • @Tsunami14
      @Tsunami14 2 місяці тому +1

      I was wondering about that.
      I know C# throws an exception if you try to do this, so I was wondering if C++ had any similar rules/protections for mutating collections with an active iterator.
      Unsurprisingly, it seems like "shooting yourself in the foot" is allowed.

  • @ciCCapROSTi
    @ciCCapROSTi Місяць тому +2

    Just a note. shared_ptr is not guaranteed to be implemented with reference counting. Therefore use_count might be a linear operation, while expired is always constant.
    13:45 I don't like this example. Smart pointers express ownership. In this case, if you can just switch to a weak pointer, then there was no ownership in the first place, and using a shared was an error. That's a case for raw pointers or references. The number places where you need a shared_ptr is massively smaller than the places where people use them.

  • @hassanalmasri3935
    @hassanalmasri3935 2 місяці тому +5

    Good evening Mr. Yan ,
    I want to thank you for your outstanding work on the game engine series and on your content on you UA-cam, it was really helpful to me.
    One of the series that i really liked was the "Ray Tracing" series and I know that you have said that it's better not to be a series on UA-cam and you didn't want to continue it there but i am asking you to consider continuing it because it's one of the greatest series on your channel ( it talks about graphics more than any other series- game engine series is focused on game engines and c++ series is on c++ , even opengl series we didn't have that much of episodes ).
    Thank you so much ❤❤
    Have a nice day 🌹

  • @pavliv
    @pavliv 2 місяці тому +18

    Oh this Shared Pointer rapper makes absolute bangers

    • @theChroma75
      @theChroma75 2 місяці тому +1

      Now i can't unhear him saying rapper 😂

  • @toni6199
    @toni6199 2 місяці тому +1

    "lots of dying going on, welcome to C++" out of context is funny as hell

  • @ChrisM541
    @ChrisM541 2 місяці тому +7

    What about Well-Endowed Pointers?

  • @dopetag
    @dopetag 2 місяці тому +1

    Explanations are always on point! Thanks for refreshing shared and unique pointers too.

  • @Basel-ll8fj
    @Basel-ll8fj 2 місяці тому +2

    Man, your explanation is really great
    thank you

  • @michadudkiewicz3902
    @michadudkiewicz3902 2 місяці тому +4

    8:20, nitpick :) This is not quite true that we can't know this. We can provide custom deleter for the shared pointer to Object that would store ref to manager and set manager.obj to nullptr shortly before Object is destroyed. The real reason is that this is still not thread safe. The object might be destroyed from a different thread after the if statement returned true. It would need to be synchronised, but we do not reinvent the wheel, cause we already have STL solution, which is std::weak_ptr

    • @mikefochtman7164
      @mikefochtman7164 2 місяці тому

      I suppose, but a custom deleter means now the Object would have a dependency on the 'manager' class. Object shared pointer has to have 'manager dependent' information (that it has to update its ref and set manager.obj to nullptr). I'd vote against this and stay with std::weak_ptr.

  • @deeplazydev
    @deeplazydev 9 днів тому

    Good explanation, thanks! I will not remove the observer while I'm iterating the list, I guess that invalidates the iterators

  • @mikk5428
    @mikk5428 2 місяці тому +1

    Cherno. You are made for educating people. Keep it up!

  • @mr.anderson5077
    @mr.anderson5077 2 місяці тому

    My man Yan is back, let's keep C++ series rolling back again

  • @CallumPooleProgrammer
    @CallumPooleProgrammer Місяць тому

    Would be good to hear more about your reasoning behind using a custom shared/weak ptr in Hazel?

  • @ScorpioHR
    @ScorpioHR 2 місяці тому

    I loved the weak reference to the Tragedy of Darth Plagueis the Wise.

  • @NickEnchev
    @NickEnchev 2 місяці тому

    I'd definitely switch to the safer code in event driven situations like these input observers since they aren't likely to get called thousands of time a second. For anything else, I'd measure and then make that decision.

  • @kiranchowdary8100
    @kiranchowdary8100 Місяць тому

    thanks for having interest in sharing knowledge

  • @jmjoebar
    @jmjoebar 2 місяці тому +7

    Nice neat example ! Great description and explanations.
    Be careful though when you call RemoveObserver(observer) inside the for loop over the observers. That may lead to undefined behavior, right ?

    • @antongrant8827
      @antongrant8827 2 місяці тому +4

      Depends on the container used to store observers. For instance, list does not Invalide iterators on remove, so you should be fine. Vector, on the other hand, does invalidate iterators on remove, so this may be UB.

    • @icestormfr
      @icestormfr 2 місяці тому

      @@antongrant8827 As it is in this case a std::vector ... well

  • @KurtVanBever
    @KurtVanBever 2 місяці тому +4

    "He's dead Jim."
    The guy looks young, but this gave it away 😂

  • @ferinzz
    @ferinzz 2 місяці тому +2

    Weird reactions to making the code safer... Personally recently went through a fundamentals course and considering all the overhead that you would normally need to manage (not just knowing lifetime but also overloading stuff) I don't understand why people can't see that this is a good starting point to ensure your code scales safely. Then if there are performance issues (somehow) work on your own better version.
    Remember, Java was created to prevent some most of the memory issues that existed before smart pointers were introduced. And a lot of companies moved to Java because of it.

  • @adrienc8716
    @adrienc8716 Місяць тому

    Hello The Cherno, could you make a video on the documentation of our code with Doxygen ?

  • @mareksb
    @mareksb 2 місяці тому

    Would love to see you make a video about C++ Modules

  • @TheRealZitroX
    @TheRealZitroX Місяць тому

    My ex excompany did use them always.
    But somehow say ended up using ton of threadlocks and workarounds instead of doing stuff like obj.lock or weakptrs. Guess it has todo with knowledge and design.
    In the end it was just threadlocks and ptrs that doesn’t got deleted🎉

  • @Zmakinator
    @Zmakinator Місяць тому

    Hello guys! That VS theme looks beautiful, could someone share where can I get it? 😮

  • @draken2037
    @draken2037 2 місяці тому +1

    We want a video on design patterns

  • @omarrashads7888
    @omarrashads7888 2 місяці тому

    great video Can I know what are those themes and plugins cherno is
    using (I catched the visual assist one )

  • @annastley
    @annastley 2 місяці тому +3

    The warm lighting in the background is very calming

  • @CHEL0VEK100
    @CHEL0VEK100 2 місяці тому

    good one, thank you

  • @isurusenanayaka4858
    @isurusenanayaka4858 Місяць тому

    I'm little bit new to the c++, but I have question, does auto obj = obj.lock() increment the reference count of the original obj? becuse obj.lock() method returns shared_ptr

    • @PCForrest
      @PCForrest Місяць тому

      Firstly, auto obj = obj.lock() is invalid C++ because you cannot have two objects with the same name (obj). I'm sure that's just a typo, but it's one of the reasons we avoid using variable names that only differ by case (Obj and obj). The Cherno really know better!
      Secondly, the return value of weak_ptr::lock() depends on whether weak_ptr::expired() evaluates true or false. If true, the return value is an empty shared_ptr which obviously does not increment any reference counts. If false, the original object is still alive, thus you get a new shared_ptr constructed from the weak_ptr, which naturally increments the reference count.
      Note that if you attempt to explicitly construct a shared_ptr from a weak_ptr, an exception is thrown if the weak_ptr has expired. This doesn't happen with lock(), which is an atomic operation.

  • @jpack61108
    @jpack61108 2 місяці тому

    Surprised the cyclical dep compiled 😮

  • @anon_y_mousse
    @anon_y_mousse 2 місяці тому

    The only question I would ask is, do you think there's something wrong with the standard pointer types that you would choose not to just use them and instead wrote your own?

  • @mr.anderson5077
    @mr.anderson5077 2 місяці тому

    Hey @The Cherno , what tool do you use to draw stuff on the screen while teaching, I mean the red markets highlight stuff.
    Does anyone knows this? kindly drop a comment

  • @VanFS3K
    @VanFS3K 2 місяці тому

    Tell me more about your own reference counting system. Why did you feel the need to make your own?

  • @PeterfoxUwU
    @PeterfoxUwU 2 місяці тому +1

    god i wish i had known this few months ago o.O
    Thank you Cherno!

  • @mjthebest7294
    @mjthebest7294 2 місяці тому

    Excellent, time to learn Jai! :o

  • @Troyseph
    @Troyseph 2 місяці тому

    You can't modify your vector of observers while you're iterating it 😬 been there before!

  • @stefanwaldegger2048
    @stefanwaldegger2048 2 місяці тому +2

    I like it a lot your explanation. I have a super convenient use case for it. I am making a game where I can shoot among others homing missiles. Those missles hold a weak_ptr to the object they are aiming to. So I dont need to handle the situation when the object gets destroyed (I can more or less just delete it) and the missles can handle the situation then

    • @matthewmatthew2946
      @matthewmatthew2946 2 місяці тому +1

      You can use some sort of entity system, that maps IDs to entities. This way, you would not have to use weak_ptr and instead just hold onto an ID of the target

  • @abzrg
    @abzrg Місяць тому

    00:00 wake pointers?

  • @Sebanisu
    @Sebanisu 2 місяці тому

    I never really understood weak ptr, till now heh. Might of been better than using shared pointer in some places. Where I couldn't figure out why I had memory leaks and such. I was probably creating things that would never get deleted.

  • @parsanasirimehr7267
    @parsanasirimehr7267 2 місяці тому

    I love it when i compare this to Swift's Automatic Reference Counter. That one does this by default to all memory, and it is pretty slick. Nice to know C++ has it too.

  • @NizarPro
    @NizarPro 2 місяці тому

    in your example at 13:34, shouldn't B get destroyed first then A ? the output confused me

    • @michaeldamolsen
      @michaeldamolsen 2 місяці тому +1

      No, A holds a shared ptr to B, keeping B alive. So A must be destroyed first.

    • @NizarPro
      @NizarPro 2 місяці тому +1

      @@michaeldamolsen It makes sense now, A preventing B destructor from now because it owns a shared pointer to it, Thanks for the clarification.

  • @dj10schannel
    @dj10schannel Місяць тому

    🤔hmmm I've not used shared ptr yet but they are indeed very useful

  • @DeepFriedOreoOffline
    @DeepFriedOreoOffline 2 місяці тому

    Is a weak pointer more efficient than doing something like if(pointer), or is it just more safe? I don't really get why people seem to be so against raw pointers, I mean, if something is going to go wrong, make it as loud as possible for easy debugging, lol.

    • @Ziflinz
      @Ziflinz Місяць тому +1

      You're actually arguing *for* weak pointers. They're slower, but safer. If you're just holding onto a raw pointer then it is possible that the object was deleted elsewhere. Nothing tells you this. It's also (quite) possible that after the object was deleted it was reallocated as a different type (or even the same type) and that can cause a very difficult to diagnose bug in your code. Using a weak_ptr ensures that your "if(pointer)" (technically the .lock() conversion to a shared_ptr) check always returns null if the object has been deleted. It also ensures that the object remains valid while using it unlike a raw pointer.
      So if you're not 100% sure of the lifetime and ownership of an object, it's worth looking into using weak_ptrs. If you are, then unique_ptr is likely a better choice than a raw pointer as it makes ownership explicit. Even when using these types, you're still left deciding which type to use for function parameters (i.e. do you use a raw pointer, a reference, or a const unique_ptr& for a function parameter that use an object stored in a unique_ptr).

    • @DeepFriedOreoOffline
      @DeepFriedOreoOffline Місяць тому

      @@Ziflinz I do understand what you mean, especially when you're dealing with large code bases, but when you say "nothing tells you if a pointer was deleted elsewhere", that is kind of why I prefer the raw pointer. Because if you get a big juicy error accessing an invalid pointer that hasn't been properly handled, you can then go and setup break points to find the problem. With something setup in a "safe" way, it is not always immediately apparent what the problem is when literally nothing happens, because the pointer is gone and the weak_ptr handles the falloff for you. In my opinion, if a pointer is being deleted when it's not supposed to be, the structure of the code is not ideal, and the sooner you know, the sooner you can restructure.

  • @vinniciusrosa8284
    @vinniciusrosa8284 2 місяці тому

    Hi, I stoped coding cause of my little son. But I always return to keep things in mind while out of c++ world.

  • @iEnjoyApplesauceVeryMuch
    @iEnjoyApplesauceVeryMuch 2 місяці тому +27

    Honestly 99% of the time you probably don't even need shared pointers. Organize your code to avoid returning structures which contain arbitrary references. For most tasks, the lifetimes of your data should be pretty obvious.

    • @-rya1146
      @-rya1146 2 місяці тому +6

      Except when it isn't

    • @Spartan322
      @Spartan322 2 місяці тому +5

      @@-rya1146 Majority of the time it is, there's very few cases where it won't be, mostly in multi-threading or maybe if your consuming someone else's work. (and even then good documentation handles 90% of the latter cases)

    • @Dienes
      @Dienes 2 місяці тому +2

      This. When I see a shared pointer in your single-threaded code, then I must assume you have no idea of your data flow. Red flag.
      Multi-threaded they can come in handy, but if there's a way to structure your flow to not need them, then really just don't use them.

    • @kidmosey
      @kidmosey 2 місяці тому +1

      @@Dienes why wouldn't you always design your code to be thread safe?
      if it's public, assume someone will use it with data that eventually scales to a million iterations, and assume it will be used asynchronously - because invariably someone will assume your api scales infinitely and is thread safe.

    • @anthonysteinerv
      @anthonysteinerv 2 місяці тому +3

      This mentality is exactly why most programs has leaked memory problems, and why people are opting out of Cpp and going for the garbage ass programming language that is rust.

  • @kidmosey
    @kidmosey 2 місяці тому

    I tend to prefer weak_ptr because, aside from the safety aspect, it adds context over just using *

  • @Spartan322
    @Spartan322 2 місяці тому +1

    I'll usually prefer unique_ptr and raw pointers for that project, a ref counted pointer is kinda pointless and wasteful unless you expect your objects to constantly go out of scope without moving their pointer object around or if you're doing multi-threaded work, something which did not happen in that project. I've found that in most single threaded programs its uncommon for me not to know when the object will go out of scope unless I build my project with exceptions.

  • @guilherme5094
    @guilherme5094 2 місяці тому

    👍Thanks.

  • @gggffffeee
    @gggffffeee Місяць тому

    what about templates ?

  • @antoine7924
    @antoine7924 2 місяці тому

    Hello The Cherno. I submitted an inquiry email a week ago to know more about the engine before becoming a Patreon, and potentially a volunteer. I still didn't get any answers for it.

  • @tamasballa1
    @tamasballa1 2 місяці тому

    Swift uses this automatic reference counting system for memory management, it is cool to see the same techniques in cpp

  • @sdegueldre
    @sdegueldre 2 місяці тому +2

    "cyclical shared pointers means the objects can never die"
    We're *this* close to hearing you talk about why garbage collection is a good idea, actually!

    • @benjaminfranklin329
      @benjaminfranklin329 2 місяці тому +1

      If an edge case was a reason not to use C++, the language would have died a million deaths.

    • @edgie8772
      @edgie8772 2 місяці тому +1

      Cyclical dependencies are more often than not just symptoms of bad design

  • @daveclark86
    @daveclark86 2 місяці тому

    Removing from the vector while iterating over it... 😬

  • @TU7OV
    @TU7OV 2 місяці тому +97

    Don't overuse shared pointers, boys.

    • @literallynull
      @literallynull 2 місяці тому +9

      Dont use them at all lol

    • @9100eric
      @9100eric 2 місяці тому +31

      @@literallynull i just used my 400th shared_ptr. what you're gonna do now?

    • @pavliv
      @pavliv 2 місяці тому +2

      Go for references instead

    • @aidenlilley1319
      @aidenlilley1319 2 місяці тому +10

      ​@@literallynullgood luck with that LMAO

    • @shadow_blader192
      @shadow_blader192 2 місяці тому +9

      Use raw pointers :))

  • @wormheamer
    @wormheamer Місяць тому

    always kinda strange to peer in on the c++ pointer caste system as a c programmer.
    very educational video though ;)

  • @user-kv1ll6lb8e
    @user-kv1ll6lb8e 2 місяці тому

    It is have been a year since I found your Chanel and every of your videos is perfect, thank you cherno, can I ask you something
    Why your name is Slavic, just want to know.

  • @makebreakrepeat
    @makebreakrepeat 2 місяці тому

    Surprisingly not pointless

  • @lMINERl
    @lMINERl 2 місяці тому +2

    No wont update my code If it works it works , we are doing it raw no protection ....

  • @williamdrum9899
    @williamdrum9899 2 місяці тому

    I've only ever used assembly so I'm totally lost

  • @xy7914
    @xy7914 2 місяці тому

    Please we need some sessions about advanced object-oriented, or to explain about when doing code review

  • @noel350
    @noel350 Місяць тому

    I both like and hate the versatility of cpp...

  • @TheTykbry
    @TheTykbry 2 місяці тому

    I think the important thing to remember is smart pointers is for ownership. When your code needs to own some other object on the heap, use smart pointers. If your function someplace just needs to work on a pointed to object (and not save it for later)? Just use raw pointers, call the function with the raw pointer from your smart pointer.

    • @TurtleKwitty
      @TurtleKwitty 2 місяці тому

      If you need to work without saving it yourself you should be taking a reference to an already existing shared/unique ptr for the duration of your call not taking raw pointers, you're borrowing the ownership of your caller and guarenteeing that you wont accidentally do something stupid with a raw pointer

    • @TheTykbry
      @TheTykbry 2 місяці тому

      @@TurtleKwitty The idea is fine, but it does not work fully. You make a function that does something with some type. you don't want a copy so you take it by pointer. Ahh but you heard raw pointers are evil, so you use a smart pointer and take it by ref because you don't actually want the ownership. But there are two smart pointer so now you need to make two overloads, and it only works for object contained in a smart pointer. We might still need to be able to work with stack allocated objects
      I think the reference is a good idea, but then do it on the contained type. Or make a non_owning pointer wrapper to be explicit about it being non owning if you don't like raw pointers. Like non_owning or something.

    • @TurtleKwitty
      @TurtleKwitty 2 місяці тому

      @@TheTykbry just take the red to the stack what the fuck xD not using raw pointers doesn't mean you randomly throw things into shared ptr for no reason XD

    • @TheTykbry
      @TheTykbry 2 місяці тому

      @@TurtleKwitty yes you don't. Exactly. But you suggested taking the smart pointer by ref, now forcing the user to do exactly that. So you should just take the parameter of what the smart pointer points to, lets say a struct S. So your function could just look like (foo(S& s) or foo(S* s), and then you would call it with a smart pointer: foo(*s_ptr.get()) for calling the ref version or foo(s_ptr.get()) for the pointer version.
      And now foo even works for non smart pointer types. Compared to what you suggested originally by taking the smart pointer by ref, somehting like this: void foo(std::shared_ptr& s), forcing every user to use a smart pointer. Got a local S or some other kind of stack bases S? Or maybe unique_ptr? Too bad, put that in a shard_ptr!

    • @TurtleKwitty
      @TurtleKwitty 2 місяці тому

      @@TheTykbry Ref yes, pointer no. The entire point is to eliminate possible foot guns, which converting back to a pointer would not do. So yes if your structure isn't always on the heap ref to it directly, if you always have a pointer ref to it directly. Your original post was about handling cases where functions take things by raw pointers to nit have the ownership overhead so the answer to the specific thing you brought up is red to the smart pointer. But yes as a general rule if you're doing things from scratch use refs everywhere possible

  • @sheraah.-1948
    @sheraah.-1948 2 місяці тому

    What if it’s a unique_ptr and not a shared_ptr🤔

    • @aarorissanen930
      @aarorissanen930 2 місяці тому

      Unique pointer has the sole ownership of an object. When the object goes out of scope, the unique pointer cleans it up. This means you can't copy a unique pointer, thus making it not-unique.
      A shared pointer has a shared ownership of an object. Every time the shared pointer is copied, the objects reference count increases, and every time a copy goes out of scope, the reference count of the object decreases. Only when the objects ref count hits zero is the object cleaned up. This prevents null pointer undefined behavior.

  • @OperationDarkside
    @OperationDarkside 2 місяці тому

    I think in all my C++ code I've ever written there was only a single case where shared and weap ptr would have been useful, but I used a raw ptr instead, because the cyclic reference was managed by the 2 cyclic classes being instantiated only once as RAII objects not as heap allocated memory. I will keep them in mind though.

  • @hawkingeta7489
    @hawkingeta7489 2 місяці тому

    Personally, I am a fan of raw pointers. Probably because when I started to work at my current company, I inherited a project to maintain that was full of std::shared_ptr. Most of them were unnecessary or incorrectly used. There was a case of a singleton that kept on dying because implementation was depended on a std::shared_ptr living throughout the program's live span. If it died, the next call to instance would create a new one and you ended up with total weird behavior that was very very very hard to track down. It was very satisfying when I did though.

    • @0LoneTech
      @0LoneTech Місяць тому

      Ah, the upgrade of global variables: obscured global variables of inconsistent volatility.
      ... I'm not sure the shared_ptr is the problem here.

  • @s1lkysl1m83
    @s1lkysl1m83 2 місяці тому

    You all should be using your own memory pool utility.

  • @severgun
    @severgun 2 місяці тому

    For me it sounds like that you MUST use smart pointers ALWAYS until you know that it's usage in exact place cause NOTICEABLE overhead.
    First make it safe. Optimize later.

    • @0LoneTech
      @0LoneTech Місяць тому

      Yep, that's a typical case of premature optimization. It's compounded by the fact that C++ and Rust make the simple, safe case far more awkward to write.

  • @BlackxesWasTaken
    @BlackxesWasTaken 2 місяці тому

    How long did you wait to do the initial joke ? Feels like you prepared your whole life for it :D

  • @victoroliari9479
    @victoroliari9479 2 місяці тому

    I feel like you’ve solved a problem that wasn’t a problem.
    Is it all just to save a 4 bits integer value on stack? In the example, the pointed object was deleted, but there was still an integer storing the adress. Why bother using weak pointer instead of raw pointers?
    I’ll watch it again.

    • @garrethutchington1663
      @garrethutchington1663 2 місяці тому +3

      The problem is that if the original pointer gets deleted, the memory it points to becomes invalid. So if you try to use your pointer to call a method or whatever, the application is going to crash because the address that your pointer is pointing to no longer contains the object.

    • @ferinzz
      @ferinzz 2 місяці тому

      the observer doesn't know (and shouldn't know) anything about the lifetime of the pointers it's holding onto. There was no other safety from invalid pointers during iteration so either they never die and as a result it's always safe or they die and something else is removing them.. but if some other system is trying to access it before it's removed the system would crash.
      Adding the barrier of the shared/weak ptr prevents potential race conditions.
      Could you still safely ensure that everything works in the right order to prevent this from happening? Sure. But that's a lot of mental overhead whereas this rewrite creates safety from within the observer itself.
      It also signals to the person sending information to the observer that this value might be used by other systems, so make sure you're keeping it safe.

    • @victoroliari9479
      @victoroliari9479 2 місяці тому

      @@ferinzz thank you for expanding the matter. I develop offline applications which receives an input file from a web application, and I couldn’t see these cases. In fact, I manually point my pointer to nullptr after deletion, and hence I can check wether it existists.
      For legacy reasons, we have our own smart pointer (not so smart at the current standard). Our pointers are incompatible with smart pointers, so I lacked this vision.
      Thank you again

    • @ferinzz
      @ferinzz 2 місяці тому

      @@victoroliari9479 Glad i could help add some perspective on the situation here.
      Making your own smart pointers that work ideally for your own systems makes sense as well! I know Unreal has their own pointer management to reduce the risks of these issues.
      It's always safe to point things to nullptr when you're done with it to reduce these risks. My understanding as a newbie is that it's easier/safer to start with smart pointers and then optimize as needed since you don't need to worry about the 5 rules if you are using these pointers.
      Haven't used them myself yet. I'll prob need to start using them on the next iteration of my csv parse.
      Thanks for sharing.

  • @matthiasgruen431
    @matthiasgruen431 2 місяці тому

    I generally don't find the need to use shared_ptr. I always use unique_ptr, so it's clear who has ownership of the object. The object can then be passed around as a raw pointer, indicating that it's just meant to be used and no ownership is transferred. I feel that shared ownership just obfuscates the code and is an indication of a design flaw.

  • @herrdingenz6295
    @herrdingenz6295 2 місяці тому

    3:36 "the powder" .. yeah sure .. take less cocaine Yan and take care of your family! :P

  • @josephlandry8787
    @josephlandry8787 2 місяці тому +10

    That’s why I use C. Pointers in C++ are pretty weak

  • @oglothenerd
    @oglothenerd 2 місяці тому +1

    Soy pointer. :3

  • @darkcaste
    @darkcaste 2 місяці тому

    Didn't you just introduce an iteration bug by removing the observer in the loop?! You'll be skipping over the next element, when some arbitrary object lifetime expires. That's scary.

  • @MapleLeavesInAutumn
    @MapleLeavesInAutumn 2 місяці тому

    Can you tell me please which text editor are you using?

    • @JavedAlam-ce4mu
      @JavedAlam-ce4mu 2 місяці тому

      Microsoft Visual Studio (the full Visual Studio, not Visual Studio Code).

    • @MapleLeavesInAutumn
      @MapleLeavesInAutumn 2 місяці тому

      @@JavedAlam-ce4mu Thank you : )

  • @pedroguidatv
    @pedroguidatv 2 місяці тому

    WeakPtrs do not modify the reference count and that's why in order to safely use the pointee you need to get a shared pointer if the pointed at object is still alive

    • @TurtleKwitty
      @TurtleKwitty 2 місяці тому +2

      It modifies the weak count not the owning count but it does track weak count

  • @Mr.Not_Sure
    @Mr.Not_Sure 2 місяці тому

    I've been coding for about 20 years and used weakptr just once, exactly to break circular dependence on destruction. (Btw it was Python if i remember correctly)

  • @andersonklein3587
    @andersonklein3587 2 місяці тому

    I honestly would have kept the original. Because if the code is designed such that an object can safely be assumed to be alive at some point there's no point in checking it. It's all about scope, if I know a variable will live within a thread I won't use mutex, for instance.

  • @CLARKINSILLO
    @CLARKINSILLO 2 місяці тому

    just change the extension to .c and call free, boom! problem solved!🤣

  • @herrdingenz6295
    @herrdingenz6295 2 місяці тому

    those pointers are just like you: weak :D

  • @hahaustin4real
    @hahaustin4real 2 місяці тому +2

    I am a weak pointer

  • @gsestream
    @gsestream 2 місяці тому +4

    pretty weak

  • @abacaabaca8131
    @abacaabaca8131 2 місяці тому

    I personally feels that the name of the method `std::shared_ptr::lock()` has little emphasis on what it does.
    Maybe some names like "rescue" or "sustain" or even "resurrect" would be much more make sense at least to me.

    • @Dienes
      @Dienes 2 місяці тому

      The term is in line with other concurrency classes of the standard, and it certainly makes more sense than "resurrect"

  • @khalidelouadi2144
    @khalidelouadi2144 2 місяці тому

    just use go

  • @BobChess
    @BobChess 2 місяці тому

    I always use new and delete. What is even smart pointer

  • @KingKarEl100
    @KingKarEl100 2 місяці тому

    Smart ptrs are designed to document and help enforce the lifetime and ownership of your memory through the compiler.
    If your codebase uses smart ptrs, you should be consistent and use smart ptrs throughout the codebase unless situation forces a raw ptr to be used or lifetime of the ptr is not exposed publicly and is tightly scoped. Each raw PTR usage is a risk of memory lifetime being misunderstood and uses after free errors
    Like the Cherno, if you feel that the std smart ptrs are not fit for your uses, make your own

    • @Dienes
      @Dienes 2 місяці тому

      "Each raw PTR usage is a risk of memory lifetime being misunderstood"
      If you don't understand your lifetimes, then this bandaid is not the fix you want. Fix your lifetimes, then reevalute if you need a shared pointer.

  • @hagbardceline9866
    @hagbardceline9866 2 місяці тому +2

    It's a great time to start learning Rust 😅

    • @pavliv
      @pavliv 2 місяці тому +1

      Good luck with that

  • @wolpumba4099
    @wolpumba4099 2 місяці тому +2

    *Summary*
    This video by The Cherno explains weak pointers in C++ and why they are useful:
    *What are weak pointers? (**0:58**)*
    * A C++ class designed to be used with shared pointers.
    * Provide a non-owning reference to an object managed by shared pointers.
    * Allow access to an object without extending its lifetime.
    * Prevent memory leaks caused by circular dependencies between shared pointers.
    *Why use weak pointers? (**5:40**)*
    * *Avoid dangling pointers:* Weak pointers provide a safe way to check if the object they point to is still alive.
    * *Break circular dependencies: (**12:49**)* When two or more objects hold shared pointers to each other, they can't be deleted. Weak pointers prevent this by only one object holding a strong reference.
    * *Observer pattern:* When an object (observer) needs to monitor another object (subject) without affecting its lifetime.
    *How to use weak pointers: (**8:38**)*
    * *Creation:* Created from a shared pointer using `std::weak_ptr weakPtr(sharedPtr);`
    * *Checking validity:* Use `weakPtr.expired()` to see if the object is alive.
    * *Accessing the object:* Use `weakPtr.lock()` to obtain a shared pointer to the object. If the object is alive, you can use the returned shared pointer. If not, `lock()` returns a null shared pointer.
    *Example use case: (**13:50**)*
    * An input handler keeping track of observer objects. Using weak pointers ensures that if an observer is deleted elsewhere, the input handler won't try to access invalid memory.
    *Key takeaways:*
    * Weak pointers are a powerful tool for managing object lifetimes in C++.
    * They are especially useful in scenarios involving shared ownership and potential circular dependencies.
    * While adding a slight overhead, they provide increased safety and robustness to your code.
    i used gemini 1.5 pro to summarize the transcript

    • @steelcock
      @steelcock 2 місяці тому

      hey that's nice!

    • @phusicus_404
      @phusicus_404 2 місяці тому

      Does it "watch" the video or read subtitles?

  • @chris52000
    @chris52000 2 місяці тому

    Atomics are pretty expensive though, right? Cache invalidation hurts

  • @Timm2003
    @Timm2003 2 місяці тому +2

    First non-bot comment

    • @gelis07
      @gelis07 2 місяці тому

      yeah, I've been noticing a ton of bots lately

  • @bundlesofun9568
    @bundlesofun9568 2 місяці тому +1

    I still just use raw ptrs, all these fancy ptr types are just silly

  • @arl-t8d
    @arl-t8d 2 місяці тому

    Don't use smart pointers. If you have memory leak it's just a skill issue.

  • @maartenofbelgium
    @maartenofbelgium 2 місяці тому

    Be careful, std::shared_ptr is not multithread safe

    • @simonmaracine4721
      @simonmaracine4721 2 місяці тому +5

      The reference increments and decrements are thread safe. The managed object data isn't.
      Saying vague things doesn't help much.

    • @chris52000
      @chris52000 2 місяці тому

      You can use them to easily manage memory in a thread safe way.
      You just have to remember that the assignment to the pointer and the underlying object are not given any thread safety.

  • @KotomichiGames
    @KotomichiGames 2 місяці тому

    your example is just bad practice :D it will never happen in the real world when you are coding for good :) it will not pass the code review :))

  • @Argoon1981
    @Argoon1981 2 місяці тому +1

    If raw pointers are so bad, why there's billions of C and even older C++ software written in the world and written through decades that use them, that worked and some still work and don't constantly crash and burn?
    What does this say of modern C++ programmers?

    • @pavliv
      @pavliv 2 місяці тому +6

      Different levels of abstraction. Try coding some modern triple A game in pure C and you will get the idea

    • @Blubiblub1
      @Blubiblub1 2 місяці тому +4

      Just because it worked, doesn't mean that it is ideal. Sure you can write software with raw pointers, but why? It's much easier and less error prone to use smart pointers.
      About "What does this say of modern C++ programmers?"
      Judging people just because they are not making it harder for themself for no reason is a weird take.

    • @Pablo360able
      @Pablo360able 2 місяці тому +1

      good point. but why stop there? if writing code by individually punching holes in cards is so bad,

    • @michaeldamolsen
      @michaeldamolsen 2 місяці тому

      "... some still work and don't constantly crash and burn?"
      - Analysis showed that a large number of bugs in shipped software were caused by double free or access to freed memory. A lot of those bugs are relatively subtle and require unusual/rare circumstances to trigger. Shared pointers are a tool that allows a programmer to make sure his code cannot have bugs of those types, with very little overhead. I don't understand what is wrong with that?

    • @Argoon1981
      @Argoon1981 2 місяці тому

      @@pavliv There's plenty of triple A games written in pure C, including full blown OS's, no matter if the software is old or new the basic principles and difficulties are the same.