Finally solve memory leaks in C++!

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

КОМЕНТАРІ • 311

  • @lolcat69
    @lolcat69 5 місяців тому +99

    in my C json parser I allocate memory only once, and it is while reading the files content, so then everything else that might need to access it's contents, like, we have a variable `"kind": "Person"`, instead of doing a copy of that memory, I just do a string view. so basically I just store the pointer to the start of the section I need from the string, and the length of it. I didn't did this in my first prototype, and for tokens I allocated 1024 bytes for each lexeme, but I figured out - mhh, maybe having a fixed limit on that is kinda stupid, and allocating 1024 extra bytes for each token is a bit of an over kill - so by doing a string view, I allocate 1 pointer + 1 size_t, so we just allocate 12 bytes in total :D ( this depends on the size of size_t in your computer and the size of a pointer, but it is still way better than allocating 1024 bytes ) so remember guys, never allocate memory if you don't need to, neither in the stack or the heap, just allocate as much memory as strictly needed for your program to work!

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +20

      epic chad project 💪💪 thanks for sharing it with us

    • @W0lfCL
      @W0lfCL 5 місяців тому +7

      As a C newcomer, thx for that gigachad advice

    • @maksymiliank5135
      @maksymiliank5135 5 місяців тому +6

      You should probably still push the string_views to a tree-like structure for fast lookups

    • @lolcat69
      @lolcat69 5 місяців тому

      @@maksymiliank5135 the whole json document is stored in a tree, the string_views are just used for identifiers and stuff like that

    • @ethernet764
      @ethernet764 5 місяців тому +1

      Currently learning about this technique in Crafting Interpreters

  • @toksic424
    @toksic424 5 місяців тому +175

    1:30 the virgin "Player *p = new Player();" vs the chad "Player p;"

    • @ltecheroffical
      @ltecheroffical 5 місяців тому

      I am a virgin and I use "Player p;"

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +16

      for real 💪💪💪💪

    • @niggacockball7995
      @niggacockball7995 5 місяців тому

      cant leak anything if everything is stored on the stack with a 1000 element array!

    • @atackhelikopter4303
      @atackhelikopter4303 5 місяців тому +10

      if you really need a lot of objects of a type and have to use the heap, i would just consider making a whole class to handle the memory alocation and deletion there and it would act just like the regular object, it's easier imo
      edit: here's how the class would look like:
      template
      class HeapObject
      {
      protected:
      T *ob;
      public:
      HeapObject()
      {ob = new T;}
      ~HeapObject()
      {delete ob;}
      void operator=(T a)
      {*ob = a;}
      /// other methods, i can't be bothered to give more examples, it's just here to show that you can do it
      T operator*()
      {return *ob;}
      };

    • @joshuaubani-wokoma4956
      @joshuaubani-wokoma4956 5 місяців тому +2

      @@atackhelikopter4303can even be an abstract class and the concrete ones will decide the implementations

  • @darkfllame
    @darkfllame 5 місяців тому +163

    that's the neat part: you don't

  • @sledgex9
    @sledgex9 5 місяців тому +19

    4:21 you can probably get rid of the call to `new` in you filedata var. Make use of the appropriate overloaded constructor to create an std::vector initialized with X elements of unsigned char zero initialized aka std::vector fileData(fileSize). And the use it like this "file.read(fileData.data(), fileData.size());". This takes advantage of the fact that a vector is guaranteed to use contiguous memory to store its elements.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +11

      yeah I actually write my code like this now usually 💪, it just wasn't worth the effort changing that code there

  • @mr.hashundredsofprivatepla3711
    @mr.hashundredsofprivatepla3711 Місяць тому +3

    0:48 Step 1: Don’t allocate memory when you don’t need to
    1:20 - Cool trick
    1:37 - Cons and pros of allocating memory on the heap
    1:54 - When to allocate on the stack or on the heap
    3:46 Step 2: If you need to allocate memory, try to use containers
    4:35 Step 3: Create specialized systems to manage memory for more difficult things

  • @sledgex9
    @sledgex9 5 місяців тому +42

    2:21 don't use raw arrays. Use std::array instead. They encode the size in them. Also the compiler would be able to make it as if you used a raw array. Aka zero overhead.

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

      Technically C arrays have the size encoded too, problem is they love to decay into generic pointers which can absolutely stab you in the back.

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

      It also has bounds checking in debug builds to help catch buffer overrun issues

    • @MaxCE
      @MaxCE 3 місяці тому +1

      ​@@Spartan322 there is a way to have a function take in a stack array, but it looks too bad and it's an additional unnecessary overload

    • @Spartan322
      @Spartan322 3 місяці тому

      @@MaxCE Yeah but because stack arrays love to decay into pointers it still has cases where it can perform unexpected results.

  • @onur_yas
    @onur_yas 5 місяців тому +43

    Since you are using containers to store your entities, your entities are on the heap (cuz the elements of a container are allocated on the heap), so you are not using stack memory at all. Besides this, nice advice!

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +27

      yes I know, but that is not my concern, my concern is to not have memory problems. 💪

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

      Contiguous heap memory, stack memory isn't a big deal when you need dynamic size tbf if you get cache locality out of it.

    • @maksymiliank5135
      @maksymiliank5135 5 місяців тому +5

      The only overhead from a heap is the allocation itself. If you allocate the objects as an array you still get all the benefits of cache locality and fast memory access of the stack. And if the size never changes then you don't need to reallocate so using this memory is essentially free.

    • @ezekieloruven
      @ezekieloruven 5 місяців тому

      ​@@lowlevelgamedev9330 but using std::vector literally comes with all of the caveats that using new and std::unique_ptr do, just wrapped up in a more convenient container. For example, you need to be ready for std::bad_alloc if you're considering that the other allocations can fail.
      Generally, I really agree with your overall message. Stack allocation is always better than heap allocation, unless you actually need to heap allocate. Using std::vector and friends is an awesome way to manage dynamically allocated memory, too. However, consider using smart pointers instead of the five raw pointers you have (unless they aren't pointers to data that is owned by the object). There's essentially no weight at all for a std::unique_ptr and they are pretty easy to use, not to mention guaranteeing freeing allocated memory in the face of code refactoring and exceptions.
      It is also good to add new tools to your toolkit!

  • @rayboblio
    @rayboblio 5 місяців тому +4

    Just the thing I needed in my current development phase. Thanks for all the great tips, I'm really enjoying your videos.

  • @Lelende
    @Lelende 5 місяців тому +48

    To be honest, avoiding the heap for any programming at all is a great rule of thumb.
    The edge cases where you'd actually need the heap are pretty few and far in between.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +5

      exactly 💪💪

    • @TheLordoftheDarkness
      @TheLordoftheDarkness 4 місяці тому +8

      I wouldn't call them "edge cases". When you want to load a large file like an image or audio, you need to store it on the heap because the stack isn't big enough. You also need the heap to store data structures like trees and graphs. Thankfully, the STL containers reduce the need for these kind of tasks but there are times when you need them.

    • @bigjango13
      @bigjango13 4 місяці тому

      ​@@TheLordoftheDarkness wouldn't mmap (or Windows equivalent) work better for that?

    • @TheLordoftheDarkness
      @TheLordoftheDarkness 4 місяці тому

      @@bigjango13 I can't tell because I still didn't learn how to use mmap. I've been willing to do so for a long time now though.
      What I can say is that malloc is implemented using mmap on modern systems (it used to be implemented using brk and sbrk) so I guess they just do the same thing.

  • @jackgauss
    @jackgauss 16 днів тому

    You have been a colossal help my dude

  • @vxcute0
    @vxcute0 7 днів тому

    for file loading also, in some cases where you know what file you want to load, you can embed the files, C23 even has a macro called #embed that is used for that.

  • @arl-t8d
    @arl-t8d 5 місяців тому +24

    std::pmr::vector my beloved

    • @zanagi
      @zanagi 5 місяців тому +1

      Is this the same like vector of pointers?

    • @arl-t8d
      @arl-t8d 5 місяців тому +7

      @@zanagi No, it's normal vector, but with different allocator (std::vector takes an allocator as second template argument). It basically allows you to preallocate memory block on stack and then suballocate from it. Allocations are fast and close in memory.

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

      I love the pmr idea, but each time I use them I end up wondering how did I write something so ugly. I think c++26 will have a stack vector. Maybe I'll be able to use it at work by 2035.

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

      @@fcolecumberri Yeah, I already moved to orthodox c++ so I don't use stl at all

  • @furuthebat
    @furuthebat 5 місяців тому +22

    Almost every component of my ECS is living on the stack 😅 .. who needs names or endless strings, user input is limited, e.g. player name is max. 24 characters.
    Expect for textures, sound and other assets ... .. there are living in the resource loader, loaded once, freed at the end.
    The only things that are RAII, are my Scenes/Levels, with init(), enter(), exit() ... Methods ... The Scene itself lives in a "Context" variable (held in the Scene manager). When switching scenes, the scene either gets "disabled" or uninit/init.
    Everything else lives in the ECS registry/world, the scenes queries the components there need.

    • @GBSCronoo
      @GBSCronoo 5 місяців тому

      So the resource loader would be on the heap? < kind of new to c++

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

      RAII is the stack though, like anything you create on the stack is managed through RAII, unless its a primitive data type, it will call the constructor on initialization and destructor on leaving the scope, that is RAII.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +4

      yo this sounds dope, I approve 💪💪

    • @maksymiliank5135
      @maksymiliank5135 5 місяців тому +1

      @@Spartan322 I assume these are defined in some top level function (maybe even in main) and passed around to other functions as pointers/references so RAII will not trigger as often

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

      @@maksymiliank5135 Doesn't matter, RAII is stack allocation and that's still the stack, the object itself may allocate on the heap, like smart pointers or vector, but all memory behavior of the object itself is on the stack and anything that doesn't allocate on the heap is stack allocated and also performs RAII.

  • @BaDitO2
    @BaDitO2 3 місяці тому +4

    it's also pretty easy to have memory leaks in languages with garbage collection.
    in java it's pretty easy to have memory leaks because you didn't dispose of an object in a specific way and then the garbage collector thinks it's still in use. and when you try to debug those issues it gets really ugly because it's hard to monitor what the garbage collector actually does. I always wish java had at least an option for doing manual memory management under certain circumstances

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  3 місяці тому

      It seems so wierd to me that you can have memory leaks in gc languages 😂😂😂😂 can java get any worse?

    • @BaDitO2
      @BaDitO2 3 місяці тому

      ​@@lowlevelgamedev9330 ofc you can in any language with gc btw not just java. it just reduces the risk of memory leaks.
      in special human error by the programer causes it in gc languages, in special when they don't know how the gc behaves in the language their working in.

  • @sealsharp
    @sealsharp 5 місяців тому +3

    I once worked for a 2d pixel retro-rpg where i did the C++ part and since we are not in the 90ies any more and devices have more than 2 megabytes of RAM we could ignore a lot of the memory management by loading a lot of stuff at the start.

  • @sledgex9
    @sledgex9 5 місяців тому +38

    2:40 let me introduce you to std::make_unique() and std::make_shared(). Almost never use the `new` operator to initialize a smart pointer.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +6

      well I don't actually use shared pointers like ever :))

    • @Quentillionaire
      @Quentillionaire 5 місяців тому

      @@lowlevelgamedev9330 shared pointers cause more problems than they solve in MOST cases so that's good. Unique pointers, however, are an improvement on using the new keyword in every single way so definitely use make_unique instead of using the new keyword if you end up needing to manage your own memory allocation, like when storing large objects on the heap.

    • @kramer3d
      @kramer3d 5 місяців тому

      @@lowlevelgamedev9330you dont have to … its still recommended to avoid new

    • @tiranito2834
      @tiranito2834 5 місяців тому +10

      And does that help you with memory fragmentation in any way? no? then what do you earn from this? the point of this video is for using stack allocated variables or preallocated static buffers for data. The more static allocations you do, the less you will need to dynamically allocate stuff, the less of a performance hit for your program (less fragmentation and less time wasted waiting for the OS to reserve a chunk of memory for you...). If you need to dynamically allocate, then do so in buffers or large chunks so that you don't have to allocate every single instance one by one individually. It's that simple. Using make_shared and make_unique does not save you from those problems. First, you should try to understand what the heap even is and how it works...

    • @sledgex9
      @sledgex9 5 місяців тому +15

      @@tiranito2834 You grossly misunderstood my comment.

  • @TheBypasser
    @TheBypasser 12 днів тому

    For a game engine, memory management outside of the very low-level renderer logic (things like pre-allocated instance buffers, temporary init buffers etc) is not needed, as, first, you need a generator routine anyway (and it may contain a linked list management without any external changes), also you need an iterator (say, myself I have at least a model and model instance structures that are created as a result of executing the corresponding generator functions, and later, on the rendering phase, I have to iterate them no matter which code and where - including a user-called script that is - did create those). Writing yet another cleanup iterator in this case is fast and simple. And yes, I prefer structures over classes for this, as I want to keep it clear that losing a pointer returned by a generator function does nothing, and also want class- (structure- in my case) relevant calls to be external, as they belong to separate modules - say, a model is controlled by the renderer, collision detector and lighting modules, and no way I want every change done to those modules having to be reflected on the base class!
    P.S. I don't use "new", I use malloc and _alloca :P

  • @EmuEmuchu
    @EmuEmuchu 25 днів тому

    I needed this ty

  • @pavlopanasiuk7297
    @pavlopanasiuk7297 14 днів тому

    I run a computational framework with lots of data processing from columnar file. With experience I came to understanding that most of the programs data either should not or may not be deallocated, if your memory usage isn't insane. I totally skip on "new" (beside graphics application), as I can predict the whole program rundown beforehand.

  • @legendcat8913
    @legendcat8913 5 місяців тому

    your channel has been invaluable to my coding hobbies, thank you!

  • @thefoxguy
    @thefoxguy 21 день тому +2

    Yeah, like people keep over-engineering their memory solutions thinking like we're in 1990 with 512MB of memory and 500hz CPUs where the overhead of using like containers is like "game-changing" while it, in reality, doesn't matter.
    Just don't worry about it too hard and have common sense (and this video).
    And then you're good to go!

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

    It boggles my mind how many people keep insisting that you need to often deal with memory management in C++, like in almost every case I've observed, if you're managing memory directly, you should be using a container of some sort, or you should be using the stack. There are even only a limited set of reasons to deal with a raw pointer directly without managing it. Ownership semantics with smart pointers even support dynamic arrays now, so why would you never not use them? Probably because people don't bother the learn C++ and just keep doing things the C way.

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

      @@bo2-x2n You don't know what a garbage collector is do you? C++ ownership semantics don't need a GC, you don't need a GC if you use RAII, unique_ptrs are literally the same performance as manually performing the allocation, so unless you're claiming that C/C++ allocations are indistinguishable in performance to Java or C#, that's a self-clown comment. (technically the unique_ptr may be able to be more performant cause there is nothing actually preventing SBO, I don't recall of any implementation that does that, but they're technically allowed to)

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

      @@bo2-x2n You need to learn what a GC is. C++ ownership semantics don't need a GC, RAII invalidates the need for a GC, unique_ptrs are literally the same performance as manually performing the allocation, so unless you're claiming that C/C++ allocations are indistinguishable in performance to Java or C#, that's a self-clown comment. (technically the unique_ptr may be able to be more performant cause there is nothing actually preventing SBO, I don't recall of any implementation that does that, but they're technically allowed to)

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

      @@bo2-x2n You need to learn what a GC is. C++ semantics don't need a GC, RAII invalidates the need for it, unique_ptrs are literally the same performance as manually performing the allocation, so unless you're claiming that C/C++ allocations are indistinguishable in performance to Java or C#, that's a self-clown comment. (technically the unique_ptr may be able to be more performant cause there is nothing actually preventing SBO, I don't recall of any implementation that does that, but they're technically allowed to)

    • @cheerwizard21
      @cheerwizard21 25 днів тому

      I don't like RAII just because they require to structure your code around OOP hierarchy in a correct way, so all your resources are created and released in the right order. That's something I was struggling with when I was doing Vulkan examples first time and tried to organize code in the way to utilize RAII. That was horrible, because the order of auto releasing memory matters a lot. So that's basically one of the main reason I still use raw pointers and I like to manually allocate and free things :)

    • @cheerwizard21
      @cheerwizard21 25 днів тому

      ​@@Spartan322I agree that RAII doesn't have a performance overhead and it really makes things simple when you are coding on that level of OOP abstraction. It makes sense, but at the same time if you are doing systems programming and you can't structure your code properly, it may not work.

  • @cheerwizard21
    @cheerwizard21 25 днів тому

    Then you need to introduce methods that will init/free resource of your class/struct. So you can't utilize a constructor/destructor. Sometimes you just need to free memory right away, with stack allocation it's not possible. To avoid performance issues and memory fragmentation, use memory pool or similar allocation strategy.

  • @yaazarai
    @yaazarai 5 місяців тому +1

    I wrote a renderer with C++/Vulkan for 2D cad stuff and even in 2-3k lines of code I use new all of 3 times to allocate some command pool objects. Don't need new that often.

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

    My programs warn whenever they leak. I have a "generalized memory pools" technique. Dynamic memory allocation is nevermore a problem.

  • @boygood4830
    @boygood4830 4 місяці тому +1

    using containers is just like using new/malloc, cuz they all allocate memories on the heap (besides themselves on the stack)

    • @az-kalaak6215
      @az-kalaak6215 Місяць тому

      yes and no, containers use the RAII way of habdeling memory.
      The constructor (or setters) allocate the memory, and the destructor ensures the memory is deleted, even if an exception is thrown. the std can throw exceptions (unless you explicitely ask it not to), same goes for most c++ libraries.

  • @MisterFanwank
    @MisterFanwank 5 місяців тому

    Allocating on the heap is fine. What matters is whether you can predict how much memory you'll need. If you can't, then you won't be able to manage your memory because you don't have a good concept of what it's doing. If you can, then it's simple to just free it all at once way later when you're done with it. As long as you're not interleaving tons of mallocs and frees you won't get into trouble, and that's to say nothing of what's possible when you realize malloc is garbage and you can easily do syscalls yourself. This is the true meaning "of don't allocate more than you need to", advice that's been misconstrued greatly over the years.

  • @zeez7777
    @zeez7777 5 місяців тому

    6:43 The index also gets invalidated, so i dont really see the benefit of this tip.
    Sure on most cases you'll save 4 bytes on 64bit cause the pointer is 8bytes and your int textureIndex would be enough for any game and is only 4.
    Apart from that, you're passing in the texturemanager and then do a read with the index.
    That still boils down to reading the underlying pointer since your std::map/unordered_map is heap allocated.
    So it my mind that is the same speed, maybe even slower. Correct me if im wrong though.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +1

      so for the first thing, for example there are 5 players each one with a skin, and they can change. The index won't be invalidated, there are always 5 players, the skin can. That was the case that I was thinking about. If the index can get invalidated you would make sure to check for that of chourse. Also for the second thing I was thinking about sending the gpu id directly, like sending the opengl id, but it doesn't matter, the speed is the same roughly but I mentioned that it can be even faster to make my point very clear.In practice it boils down to how the compiler optimizes it and it is the case that for this thing it can be slightly faster or slower but very small difference

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

    people think there is a limit to the stack size there isn't the at least on windows the exe NT headers contain a 64 bit slot for the stack size needed by the program

  • @jasoniswrongabouteverythin8230
    @jasoniswrongabouteverythin8230 5 днів тому

    How do you feel about manual memory management?

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

    If you don't handle threads at the end of program then it will crash and take even longer to close.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +6

      that is another story, and they crash because that is a mechanism made by the cpp standard library, to help you not forget to either detatch them or join them. If you make them using windows api I don't think it will crash

  • @R2Sam
    @R2Sam 4 місяці тому

    What would you then suggest when you have a situation where class A has a member B, but which it doesn't want to initalize straight on A construction, as perhaps it has to do something else first. One could then just let B have an empty constructor and use an Init method but this then goes against RAII, so it seems to me like the only two options in this case is break RAII or use a unique_ptr

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  4 місяці тому +3

      break the raii principle lol, I use an init method all the time, and I have a deinit method. Besides std vector and other containers I don't have any raii in my code. For many cases its very convinient to write code like that.

    • @R2Sam
      @R2Sam 4 місяці тому +1

      ​@@lowlevelgamedev9330Why not use std::optional?

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

    Ayoo step 3 is how I do it in JavaScript even though it is not necessary. It just feels right.

  • @andersr9545
    @andersr9545 4 місяці тому

    Could you make a more detailed video about memory arenas?

  • @purpasmart_4831
    @purpasmart_4831 3 місяці тому +1

    Never heard of valgrind? I use that quite a bit, helps quite a bit.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  3 місяці тому

      I am on windows, tho fortunatelly I dom't really need it. Also I don't think it can help with gpu memory :(( I usually have to deal with that more often

    • @purpasmart_4831
      @purpasmart_4831 3 місяці тому

      ​@@lowlevelgamedev9330 Ooof Windows, my condolences. Switching over to linux made my life as Dev so much better. Anways I recommend you add some debug logic that keeps track of allocated vram, maybe add it to a debug overlay or something along the lines.

  • @erc0re526
    @erc0re526 5 місяців тому +1

    Love your content. Are you planning to make a video on your coding style/structure ?

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +4

      yo that is a good idea, yes 💪

    • @erc0re526
      @erc0re526 5 місяців тому

      @@lowlevelgamedev9330 nice!! I noticed your conventions seem clear, no bullshit, efficient !

  • @shadow_blader192
    @shadow_blader192 5 місяців тому +1

    1:58 how do you see size and alignment of class? :)

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +1

      idk just visual studio tells me, maybe it is the productivity powertools extension that I have but I think it is just a visual studio feature

    • @shadow_blader192
      @shadow_blader192 5 місяців тому

      @@lowlevelgamedev9330 ok thanks 👍

    • @somedudenamedanthony
      @somedudenamedanthony 5 місяців тому +1

      That's provided by a Linter/LSP like Intellisense or clangd.
      (Finding the size of a structure of class.)
      Just use the (sizeof) keyword/function.
      -It's not hard to do the math yourself if you know the size of element the class is holding.-
      -Lets say you have a "Position2D" or "Point2D" class, it obviously needs to numbers to represent the coordinates, so 2 integers/floats (4 bytes * 2 elements).-
      -You might also want a constructor, in this example we'll treat them like function pointers, which on a 64-bit architecture is 8 bytes (a.k.a. a long pointer.)-
      -That's 16 bytes, not including the default class functions that modern C++ provides.-
      Finding the padding is near impossible to do programmatically as it's determined by the compiler.
      (This is why clangd and Sonar Lint suggest you state the padding of each element in a structure.)
      This is all from my understand(ing), I might be wrong so it's best to do your research.

    • @shadow_blader192
      @shadow_blader192 5 місяців тому

      @@somedudenamedanthony why tf you wrote all that. I goggled it, I update visual studio. Will test it later

  • @TheOptimus1200
    @TheOptimus1200 5 місяців тому +3

    Basically, if you need to deal with memory allocation:
    1. Thou shalt call one 'delete' for every 'new'.
    2. Separate memory management tasks from other tasks.
    3. The "big 3" for a class with memory allocation to avoid crashing: copy constructor and assignment operator for deep copies, and destructor for cleanup.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому

      I mean 1 is an oversimplification, if you have a simple system you do that or raii, but for a complicated system it won't look as clean

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

      1. Just use smart pointers

  • @Rioni
    @Rioni 4 місяці тому

    How do you handle id invalidation? If you were to create a large complex game, you can't have all rresources loaded from the beggining, and the int index variable might point to an incorrect resource when the resource manager has to delete elements

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  4 місяці тому +1

      good questoon, I wod store them in an unordered map, and if an entity is deleted, it just will dissapear from the map, so I can just check if the entry is in the map to know if it exists

  • @carmelo5991
    @carmelo5991 5 місяців тому

    2:50 es mejor usar std::make_unique si no vas a inicializar el std::unique_ptr con un destructor personalizado es mejor porque:
    - Sigue la regla de evitar el uso de "new" porque actualmente hay mejores opciones para manejar la memoria
    - "auto p = std::make_unique()" es más corto y conciso que "std::unique_ptr p(new Player{})
    - std::unique_ptr está implementado para ser seguro ante las excepciones

  • @lememz
    @lememz 5 місяців тому +1

    there's also alloca if you wanna allocate something of unknown size on the stack, yet another L for the heap

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому

      yeah but you shouldn't really use that as far as I know, it can have very wierd problems

    • @lememz
      @lememz 5 місяців тому +1

      @@lowlevelgamedev9330 it's only really problematic if you still treat it as a heap allocation since it's always going to get popped at the end of the scope, so just don't do dumb stuff like returning the pointer or passing it around to other threads and it's pretty much fine to use, it's perfect for small stuff like the opengl shader compilation message

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

    So this is why people say C++ isn't memory safe.
    I never understood this. I almost never use new. Like ever. It feels like reinventing the wheel, so I only do it when absolutely needed.

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

      "So this is why people say C++ isn't memory safe."
      People say that cause the language it self is not memory-safe and sadly many of the old folks start by first teaching their half-knowledge of C and then their abysmal pre C++98 style.

    • @LokiScarletWasHere
      @LokiScarletWasHere 3 місяці тому

      @@ABaumstumpf By that reasoning no language is safe.
      Some are just more restrictive than others.

    • @ABaumstumpf
      @ABaumstumpf 3 місяці тому +1

      @@LokiScarletWasHere There are many languages where simple memory access it checked - there is nothing in C++ preventing you from creating an array of 2 elements and then writing to the 1235235 index. You can create a pointer to any arbitrary memorylocation and write to it. That is what i means with the language is not memory safe.

    • @LokiScarletWasHere
      @LokiScarletWasHere 3 місяці тому

      @@ABaumstumpf Again, no language is safe. Some are just more restrictive than others.
      You just have to get a bit more creative with more restrictive languages if you want to make something that'll compile but segfault.
      Safety does not exist outside the programmer and there is no free lunch.
      Even the choice of language, how many training wheels the programmer rides with, is a decision by the programmer, or a decision made for the programmer if the code already existed before they entered the project.

    • @ABaumstumpf
      @ABaumstumpf 3 місяці тому

      @@LokiScarletWasHere Ah, so you are just intentionally pedantic and dishonest - then have fun.

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

    I always get a crisis when I can't use a stack.

  • @jupiterbjy
    @jupiterbjy 5 місяців тому +1

    Totally agre on 1:30. Some seems to use alloc & pointers way too much even when not needed - just KISS! (Keep It Simple, Stupid)

  • @vanisso
    @vanisso 3 місяці тому

    you got a pdf or something?

  • @FurryNonsense
    @FurryNonsense 4 місяці тому +1

    I had a stroke reading that title

    • @oracuda
      @oracuda 4 місяці тому

      its gramatically correct but its understandable coming from a f*rry

  • @bait6571
    @bait6571 4 місяці тому

    Anyone have a link to an explainer on why heap allocated memory may be accessed slower?
    I thought access times after allocation/the first access would be just as fast as stack allocated memory.

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

      The stack is on the hot code path so more likely to be in the cache, also the heap can be fragmented resulting in non contiguious memory which inhibits prefetching to the cache, and multiple layers of indirection like vector of vectors will makes this much much worse.
      If you are interesting data oriented design is what you need to look at.

  • @sakamocat
    @sakamocat 5 місяців тому

    about allocating on the heap, inst it useful for class dependency management?
    like, hear me out... usually i have a codebase that only uses makefiles and very frequent OOP (don't ask why, i just don't have patience to learn CMake), and by doing so, i frequently encounter problems with changing a certain class to add a new member causing me to recompile the entire project only to make the dependant classes work accordingly, because if i don't, i can start modifying data that i shouldn't be or just cause some really "undebuggable" issues. so my usual solution is to abstract each member with a getter and a setter function, so i don't have to worry about using the . or the -> operator in raw members and alignment, since it will be dealt with when compiling the single c++ file.
    however i do understand where you come from... nice tips!

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому

      that doesn't really sound good :))) and I also don't get how what you are describing has to do with the heap

    • @sakamocat
      @sakamocat 5 місяців тому

      @@lowlevelgamedev9330 if i use the stack, the size for structs and classes will be fixed, like:
      struct A {};
      struct B { A a; int bar; };
      So, ignoring the class optimization thing that some compilers do, and considering that A and B are on different headers and .cpp files respectively, if I change A to this:
      struct A { int foo; };
      For the .cpp file of B, it still thinks that A has not changed, but A has changed, so A.foo becames the same as B.bar, making some really weird bugs and eventually leading to UB.
      My fix is to defined the heap allocator for each class inside the .cpp files and wrap foo and bar with getters and setters

  • @Vixikats
    @Vixikats 3 місяці тому +8

    I wish the entirety of the r/Cplusplus subreddit would watch this video and stop for one post crying about pointers and memory unsafety. Computer memory is NOT that complex. You allocate bytes. Write shit into them. And then deallocate them. You can do 3 things with memory. If you make it more complicated than that, that's on you.

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

      Totally agree, also it's funny that I never use smart pointers and I don't complain about memory problems :)))

  • @zanagi
    @zanagi 5 місяців тому

    Was thinking about this, but my school's game engine uses shared_ptr GameObject and components as a base. Im not sure how i can code without any ptr.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +3

      well you know all the schools do that but you don't have to do the same in your code 💪💪 their example is just a simple didactic thing, I don't even use ecs in my games lol

  • @lehisluguer9300
    @lehisluguer9300 5 місяців тому +1

    also Destroyers are usefull to make sure delete stuff as soon the Class is destroyed..

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

      well I don't use destroyers in my coding style, except you know vectors and stuff have them, maybe I will make a video on it

    • @lehisluguer9300
      @lehisluguer9300 5 місяців тому

      @@lowlevelgamedev9330 oh ok.. that's fair.. yeah, vectors does the job automatically so.. its ok..

  • @devu4740
    @devu4740 5 місяців тому

    When i did texture manager for my little doom like engine because of memory leaks everyone called me stupid. But look at me now i was stupid but at least solution was smart.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому

      lol that's how top gamedevs do it in game dev. If you look at top gamedev programmers that's what they talk about and they don't use unity they make unity :))

  • @cayman_islands
    @cayman_islands 4 місяці тому +1

    music name?

  • @ashley_noveyplush
    @ashley_noveyplush 4 місяці тому

    The stack 🗿 we really underestimate it

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  4 місяці тому +1

      yes fr, you can't really fill it unless you do recursive stuff or really have some big classes

  • @nazihboudaakkar8117
    @nazihboudaakkar8117 5 місяців тому

    Okay, you touched on a subject I've been wanting to know about for long lol
    I have a question tho, I remember once having a vector of entities, the vector was getting passed around quite a lot, you see I have this preference of passing things as parameters instead of making them accessible globally or make a system for them (Unless the need arises)
    However, I had a big problem where the entities vector was getting corrupted somehow? I don't really understand the problem myself but I remember it had an addressing issue, it got fixed when I allocated the entities on the heap
    So my question: if this is wrong, how wrong is it? and how can I potentially fix it?

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

      You either used the vector wrong or one of the functions you passed it in mutate it accidentally. Either pass it as a const reference (no mutation possible) or as a reference (mutation possible).

    • @nazihboudaakkar8117
      @nazihboudaakkar8117 5 місяців тому

      @@sledgex9 I am sure I was not mutating, the vectors got passed as a "const &" since it was large
      The issue is that i noticed is that the entities within had different addresses for some reason, which was very strange to me

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

      @@nazihboudaakkar8117 Unfortunately this kind of problem can't be diagnosed via a comment. All I can say is that vectors should work with no problems. Potentially a misuse was happening somewhere. C++ has many pitfalls you can fall into if you aren't experienced, unfortunately.

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

      If you take a pointer to an item in a vector and then you add/remove things from the vector, it will invalidate the pointer because under the hood reallocation happened.

    • @nazihboudaakkar8117
      @nazihboudaakkar8117 5 місяців тому

      @@swansonair As I said earlier, I was passing the vector around as a const reference precisely to avoid that and to avoid needlessly copying the contents
      The issue got solved the moment i changed the entities to be on the heap, I clearly remember not touching anything (besides refactoring things to use the unique_ptr) and It felt sooo awkward
      But yeah, it was probably a bug on my part

  • @RawFish2DChannel
    @RawFish2DChannel 5 місяців тому +1

    Question: How to avoid memory leaks when allocation new objects?
    Answer: Don't
    👍
    Also you can allocate stuff upfront and use them as needed

  • @vladsiaev12
    @vladsiaev12 5 місяців тому

    what if you have a function that returns int how do you check for error code?

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +1

      well I would return an error code as an enum, or, if I need a return, I could take an extra parameter, as a refference, to write the error into that.

  • @givikap120
    @givikap120 22 дні тому

    Not using heap pretty much blocks you from using big chunk of polymorphism

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  22 дні тому

      💀

    • @givikap120
      @givikap120 22 дні тому

      @lowlevelgamedev9330 how can you have hierarchy of class Weapon if you can't use virtual method Attack overload

    • @santitabnavascues8673
      @santitabnavascues8673 19 днів тому

      with a function pointer, for example. Under the hood, that's how polymorphism works. Every polymorphic object has a vtable to dynamically link functions, just guess what does it store...

  • @trenwar
    @trenwar 5 місяців тому +5

    So basically code C++ like how you code in C, only use C++ features if necessary, and avoid unnecessary use of heap

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +3

      yes you got it 💪💪 advanced cpp is usefull for things like std::vector but its just too complicated to write that every day

  • @flyingsl0ths
    @flyingsl0ths 5 місяців тому +6

    all these memory leaks are from people using c with classes not c++

    • @daemoncluster
      @daemoncluster 3 місяці тому

      There are no classes in C, lol. Wtf are you going on about?

    • @flyingsl0ths
      @flyingsl0ths 3 місяці тому +1

      @@daemoncluster it’s what that style of programming is called. It’ll claim to be c++ but the programmer will lean more towards the C side of things and only use a small percentage of features from c++ (i.e. the classes)

    • @daemoncluster
      @daemoncluster 3 місяці тому +1

      @@flyingsl0ths Yeah, because C++ is a overly complicated and redundant mess. Even the creators and maintainers can't keep it straight. People think all C is missing is support for classes and automated memory management. C++ went above, beyond, and into completely esoteric territory with features like meta-programming, generics, etc. C is not easy, but it doesn't have the mental overhead that C++ tempts you with. Regardless, C with classes just ends up being C++ anyways, so it's not really an accurate statement, even if it is simply just an offhanded pejorative statement; I understand it's sarcasm and what it implies, I just disagree because of the veiled condescension.

  • @cnota69
    @cnota69 4 місяці тому

    I am also making a clone of minecraft and have not yet used the keyword “new” (and will not use it)

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  4 місяці тому

      most chad dev in the room, you can send me a link in my discord and tag me I'm curious

  • @xx_sad_dam_whose_sane_xx
    @xx_sad_dam_whose_sane_xx 5 місяців тому

    Doesn't not deallocating at the end of a program cause memory leaks and also the possibility to loose the data, just like if you force terminated the program in task manager?

    • @saniancreations
      @saniancreations 5 місяців тому +10

      No, none of those actions leak any memory. It it the job of the OS to ensure that all memory from a process is reclaimed, if it didn't do that your memory would be gone in no-time (a program crashed and couldn't free its memory? Another 20MB never to be recovered! Nah...). So when a program terminates, either normally or forcefully (like with taskmgr), the OS will reclaim any memory that the process had not yet freed. Therefore, freeing when you are about to terminate your program is pointless, you're doing work that the os is going to do anyway, and when the os does it, it quickly cleans all your memory in one go instead of slowly one object at a time, which is what your own code has to do. All of this is also why it is okay to prototype code with leaks, it's not possible to eat away at the memory in between re-compiles, stopping the exe wipes away all leaks.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому

      yes as the other comment suggested the os will clear everythingvery easily. Also most programs have leaks so it would have been a disaster if it didn't 😂😂

    • @xx_sad_dam_whose_sane_xx
      @xx_sad_dam_whose_sane_xx 5 місяців тому

      @@saniancreations I'm still in college (so I'm still a learner), we did plenty of tasks with memory allocation in C, and they told us to always clear the memory after we stopped using it. If you don't deallocate before the program ends and you run it with fsanitizer or Valgrind it will tell you that you have memory leaks

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

      @@xx_sad_dam_whose_sane_xx That's because the expectation is that a memory leak is a bug in your program that had it been left running, would be unrecoverable memory without termination.

    • @saniancreations
      @saniancreations 5 місяців тому

      @@xx_sad_dam_whose_sane_xx Memory leaks are a problem so long as your application is running. When your program stops, all the leaks go away. If you have a program that runs for a long time or it performs a repeated operation, then not freeing memory is an issue because the memory usage accumulates over time, slowly growing bigger and bigger. _That_ is what you want to avoid. Most external diagnostic tools indiscriminately look at _all_ allocations, marking anything that is never freed as a leak. But not everything that isn't freed will cause your program to infinitely grow. For example, doing a one-time allocation at start-up and using it for the duration of the program will not grow your memory footprint over time. The only moment you need to free it is at the end, and in that case the OS can do it for you.
      I like to image leaks as actual water: A single droplet is okay. Not a leak. A glass of water is okay. Still not a leak. I can have a whole swimming pool in my house and that is still fine, because I deliberately put it there and it has a finite amount of water in it. But a _leak_ is a hole in your program, water pours out the hole indefinitely, until your house is flooded. That's a problem.
      But, "not freeing" is something you need to be careful with. If you _think_ you only allocate something once, but that code gets executed _again_ every so often through a weird edge-case, then you still have a leak on your hands, then your usage _will_ grow over time. So as a rule of thumb it is generally recommended to free all memory, just to be safe and to prevent stupid mistakes.
      In practice, for many small programs that have a clear beginning and end, not freeing memory is actually fine, it gets some memory to do a job, then it terminates and all the memory is cleaned up no-problemo. Pouring some water on the floor isn't a big deal if your house is about to get demolished. But if you have a large loop that can run an unknown number of iterations, you could end up pouring a thousand+ buckets of water on the floor, and you'll drown before the demolition crew gets there.

  • @kenarnarayaka
    @kenarnarayaka 5 місяців тому

    Never understood why heap allocation was used so much, still don't and my projects run fine
    I should really learn though

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

    So you are coding in C but saving the file as a .cpp ? Then code in C

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

      I do use vectors, just because cpp has a feature it doesn't mean I have to do it. There are modern languages like zig that have no private variables or no exceptions

    • @romangeneral23
      @romangeneral23 5 місяців тому

      @@lowlevelgamedev9330 Right and one day zig will replace C. I enjoy your videos for the record they are awesome and well done. But please understand something on this level of advise. There are two programming languages. There is C, and there is C++. There is no such thing as C/C++ programming language. These tricks for memory leaks and all that is all C language stuff and not C++. This causes confusion to new comers who want to learn C++. If you going to use C++ but code in C style then just code in C. If there is a feature of C++ you like then use it properly. This makes the codebase all over the place and introduces code rot.
      Zig for the record is awesome and I cannot wait for its 1.0 release!

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

      ​@@romangeneral23 Sorry, but what makes this code "C style" rather than C++ style? Using automatic resource lifetime management with things like the stack, vector, unique_ptr, etc is very much a C++ thing and one C can't do and it's community has resisted adding.
      If you mean making classes and/or using inheritance, it is by no means C++ style to force those into a design without a reason. Same with exceptions. Same with new. Same with every other feature.
      I think you have the misconception. C++ is very much _not_ about forcing you into a particular style or design, but about giving you tools to meet the needs of your particular application. Nothing about the language forces you to use something you don't need.

    • @insentia8424
      @insentia8424 5 місяців тому +1

      @@oracleoftroy The stack is not a C++ thing, nor is a it a thing C has no access to. It's specific to the OS and architecture you are programming for.

    • @oracleoftroy
      @oracleoftroy 5 місяців тому

      @@insentia8424 Automatic resource management that is based on the stack absolutely is a thing in C++. Look up RAII and how destructors work if you aren't familiar with it.

  • @Kioki1-x8p
    @Kioki1-x8p 3 місяці тому

    Let me tell you something about C++ & C based languages, there was a programming language & framework created for it that was forefront technology for web, it ended due to security & memory leak issues. What do I mean by this? The language built upon C++ was great but the base (C++ itself) was by design at fault causing the higher level programming language to often have security issues or poor memory management despite the language being managed by a very powerful company called Adobe.
    Lesson? Don't use languages that have failed to grow primarily due to faults in the programming language use proper programming languages that address this issues to avoid future problems.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  3 місяці тому

      aircrafts and nasa still use c and cpp. I think it is kinda important for them to not have leaks

    • @Kioki1-x8p
      @Kioki1-x8p 3 місяці тому

      @@lowlevelgamedev9330 I'll provide another study case, one regarding chrome (modern browser) & another with software from the past that had to be axed due to inherent issues with C++ or C. Chrome has had 4 Zero Day exploits in 2024, one involving issue with C++, A "type confusion" vulnerability occurs when a program allocates a piece of memory to hold a certain type of data but mistakenly interprets the data as a different type. This can lead to crashes, data corruption, as well as arbitrary code execution. Internet Explorer had similar issue again. This issue is from unsafe languages along with poor programming principles. In the long run one can't predict how secure their software might be. Internet Explorer in the past case had also similar issue with 4 exploits linked with issue in C/C++ this has resulted in businesses dumping the program altogether or using an alternative to build on top of (Edge Chromium). The main issue that needs to be addressed is poor programming principles, unsafe languages & whether programmers should opt for safer alternatives like RUST or GO, etc.,
      As for NASA, this again falls on the programmer & how skilled they are.
      Again, what we can learn from this is that if there are better programmers chances of past mistakes can be lowered, but it doesn't hurt to experiment with other alternatives.

  • @freemorger
    @freemorger 17 днів тому

    just use rust?

  • @pete-i7p
    @pete-i7p 5 місяців тому

    Man this is amazing, you could probably make a prototype game like mount and blade warband with your engine.

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

    just deallocate whatever you allocate, duhh 🙄

  • @melficexd
    @melficexd 5 місяців тому +3

    I never use "new". Not even once.
    I use malloc. 🤣

  • @u9vata
    @u9vata 5 місяців тому

    Very well put together video - I literally program nearly the same way, just with a bit more raii and also changing some of your rare usage of "new" keyword with malloc in my case for arrays - but as you point out: memory resources get so rarely hand-managed when done well that its a no-problem.
    This is also why I am not interested in rust - they solve a problem very complicatedly that with a good style one can easily solve themselves. Then rust fanboys compare newly written codes from them with hugely legacy decades old codebases with old style never looking like this to prove.... what exactly?

    • @nb94840
      @nb94840 5 місяців тому +1

      Fully agree, for me its the same

  • @xd-hood-classic
    @xd-hood-classic 5 місяців тому

    which font did you use in the video?

  • @TryboBike
    @TryboBike 3 місяці тому

    I hate people who overuse input arguments with a passion of a thousand suns.

  • @blkkatana
    @blkkatana 5 місяців тому

    4:54 Isn't that called... handles?

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

    I'm gonna be that person... Just use rust 😄

  • @dimi144
    @dimi144 5 місяців тому

    7:21 this is not good advice, if it takes long for your program to do deallocations, simply hide your window to do it. It won't get in the user's way and you'll also be 100% sure that no resources were leaked

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

      why dealocate in the first place, there is no such thing as leaking anything once you close your program. RAM VRAM loaded dlls handles, everything is cleared by the os when you exit, and it is also faster

  • @Volt-Eye.
    @Volt-Eye. 5 місяців тому

    This vdo has enlighten me that I don't need Cpp for my game programming.
    Its just Good for Backend
    Who uses Cpp for Platformer

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +4

      what :) who uses cpp for backend. Cpp is used for gamedev very often

    • @Volt-Eye.
      @Volt-Eye. 5 місяців тому

      @@lowlevelgamedev9330 by Backend I mean Core of the engine not the cream part of a Game.
      Ofcourse you might have a F 35 but who uses it to go to grocessory store.
      Just use a LMEV

  • @yehezkelshb
    @yehezkelshb 4 місяці тому

    It makes me sad to see you used C++ for 10 years, and still didn't know to implement assignment operators as copy/move-and-swap, or trying to use forward with const T& (it's relevant only for T&&). 😢

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  4 місяці тому

      honestly I never implemented that operator except for that example 😂 so its not incredible the fact that I didn't do it properly. I don't use those features in my daily code

  • @subhodeepmondal7937
    @subhodeepmondal7937 13 днів тому

    ~classname(){if(ptr) delete [] ptr; }

  • @anthonysteinerv
    @anthonysteinerv 5 місяців тому

    Well, I hate checking for iterator invalidation, plus vector is heap only, so bragging about not using smart pointers even with make_unique or make_shared is kind of crazy. Plus, I'm like 70% sure that vector is not actually guaranteed to be allocated contiguously. But yeah, temporary and arena allocators are great techniques, and in fact memory management systems are kind of crazy in big game engines.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому

      well the point is not to have leaks so I don't care that vector is also heap, I just care that it doesn't leak like an unique pointer. Also yes the vector is 100% guaranteed to be contiguously.

  • @da3l_525
    @da3l_525 3 дні тому

    ok but what sort of things do you do when not using polymorphism? LOL

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  3 дні тому

      try coding without it, you'll see that it isn't at all the only solution, if you need something to behave in different ways you can just have a type as a number associated with it, or just hold dofferent classes types in different vectors

  • @williamdrum9899
    @williamdrum9899 5 місяців тому +3

    It used to be so easy. Nowadays computers are so complex nobody knows how they really work so we end up confusing ourselves further

    • @desenhonatorre
      @desenhonatorre 5 місяців тому

      I think it depends on the programming language, for example, C and C++ always had problems with memory allocation and pointers. But newer languages have other big issues. So you have to find the best fit and dive into it.

    • @williamdrum9899
      @williamdrum9899 5 місяців тому +3

      @@desenhonatorre I firmly believe that C is the reason pointers are confusing. In assembly they're not that hard to grasp

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

      @@williamdrum9899 people are confused at pointers because they only learn what it does, not why it does that. so they dont understand why would they use them

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

    -fsanitize=address

  • @SergLapin
    @SergLapin 14 днів тому

    I see all that "elegant" code all the times which "optimizes" memory use by allocating everything by teaspoon. Bookmarked the video to recommend to noobs instead of explaining what's wrong with their code.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  14 днів тому

      thank you bro 💪💪 glad it helps

    • @SergLapin
      @SergLapin 14 днів тому

      @@lowlevelgamedev9330 I religiously pass pointers to southbound calls only and avoid at all costs memory returned from those calls. Always get memory on the stack or heap from northbound interface or locally. This helps to allocate and free memory in one scope, no if's or but's where pointers become invalid. And globals are actually a good thing in moderation. NASA has 10 rules of coding, highly recommended.

  • @GabrielBON-fu4ow
    @GabrielBON-fu4ow 5 місяців тому

    malloca 🧐

  • @ItsBaffledd
    @ItsBaffledd 5 місяців тому +1

    - Look at me I dont use new anywhere really
    - Oh, btw I just use containers and obfuscate the new calls and allocations, dw shh

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +1

      well yes but that means I don't have leaking problems, what were you expecting, getting rid of leaks magically?

  • @W0lfCL
    @W0lfCL 5 місяців тому +1

    Simple trick: you don't deal with memory leaks, you just but more RAM

  • @skeleton_craftGaming
    @skeleton_craftGaming 5 місяців тому

    Except for using smart pointers are semantically equivalent to using raw pointers correctly. Except for you. Don't have to actually generate the code to use them correctly yourself? [That is to say your code is probably buggy because you're not atomically reference counting your allocated pointers; there is a reason they do that in the standard library] And you're probably also actually leaking memory to the operating system [Windows really doesn't like you using opengl so they don't consistently free on exit vram allocated for opengl/Vulcan...] Which is the only explanation for your application taking longer to close when you actually properly free your memory which you should always do without question... Especially if you're only making five calls to new anyway.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому

      um I didn't really understood your comment but windows without question will free all the resources and it will do it quickly :))

    • @skeleton_craftGaming
      @skeleton_craftGaming 5 місяців тому

      My main point is that there is no valid reason to use the new keyword outside of a constructor, and even then you should tread carefully. And also no windows does not consistently free on exit. I've had, as recently as today, programs crash and stay resident and not boot because of that..

    • @skeleton_craftGaming
      @skeleton_craftGaming 5 місяців тому

      But to clarify exactly what I said, using the standard template library's unique_ptr type generates the exact same code as T:: operator new assuming you do not copy... And if you do copy, you are probably introducing bugs by not implementing a reference counter

  • @notarandom7
    @notarandom7 5 місяців тому +6

    the last tip is horrible. not deallocating memory is just generally bad practice and should be avoided. the amount of time it takes to do that doesn't take that long and if you have so much memory allocated that it takes a while to close you just did something completely wrong

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +9

      have you ever waited for a program to close? it happened to me. So tell me why should I dealocate the memory for textures that I use for my entire game? That's just waisted work. It is true that it probably won't take long but you don't have any reason to do it either

    • @notarandom7
      @notarandom7 5 місяців тому

      @@lowlevelgamedev9330 because you're closing your program, you don't need the texture anymore

    • @SianaGearz
      @SianaGearz 5 місяців тому

      @@lowlevelgamedev9330 I mean if it takes that long to deallocate everything, you are almost guaranteed abusing malloc somewhat fierce with way too many small allocations. You have yourself shown strategies here to stop doing that. Sure you can just leave everything be on exit but that precludes the use of leak analysis tools and the like, which is not ideal.

    • @tiranito2834
      @tiranito2834 5 місяців тому +1

      ​@@lowlevelgamedev9330 Exactly. The only reason one would consider deallocating everything at the end would either be for correctness sake or because of the possibility of running that code on a system that doesn't free memory after a process is closed. To date, there is literally not a single active operating system that works like this, so... you are 100% correct. Not deallocating things that are going to be static is pretty much standard in the industry and is guaranteed to work basically everywhere. I mean, after all, what exactly is the difference between allocating a static buffer at compile time and allocating a heap buffer during runtime at the start of your program? the OS follows the exact same steps when loading the program and assigning the memory segments to the address space of the program. The only difference is that one is a static buffer with a size known at compile time, and the other is a static buffer with a size known during runtime (useful for loading files that can be modified, such as textures or any other assets).
      Besides... when you deallocate, your program is going to take longer between all the sleeping that the OS is going to put it through while its deallocating the reserved memory. Just closing the process allows the program to shut down visually for the user and then the OS can do the cleanup afterwards without having to make the end user wait any time for the program to shut down. This is just a common practice in the games industry, and one of the few practices that are actually good. I can understand people not liking it because it feels dirty, but it is still correctly exploiting the inner workings of the systems where the code will run, so...

    • @ohwow2074
      @ohwow2074 5 місяців тому +9

      Not deallocating memory is fine. Not closing a file or socket is not fine.

  • @lukasjetu9776
    @lukasjetu9776 5 місяців тому

    hello

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

    My wife left me

  • @santitabnavascues8673
    @santitabnavascues8673 5 місяців тому

    Don't go Java. Everything is a pointer there. And have memory leaks.
    The stack is limited in size, all of your static data has to fit in it, and depending on the compiler it can be as little as 16kb to as much as 16mb, so there is also the risk of a stack overflow... and... you don't know how many times they slip in "new" for you in your new-less code, sorry to break the bubble... But that's the RAII paradigm for you.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому

      can you have leaks in java? I didn't know that, if you have some details I would love to hear them so you can tag me on my discord 💪💪

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

      @@lowlevelgamedev9330 Not unless the JVM GC has a memory leak. The GC ensures there are no memory leaks.

    • @santitabnavascues8673
      @santitabnavascues8673 5 місяців тому

      @lowlevelgamedev9330 it is a myth Java doesn't leak. You simply have to mess the references to an object by not deleting appropriately containers or other kind of faulty memory management ua-cam.com/video/Ml-jZipUzPk/v-deo.html

    • @diadetediotedio6918
      @diadetediotedio6918 5 місяців тому

      ​@@Spartan322
      I mean, "leak" in the sense that it is lost memory you can't have (usually), but you can still "leak" memory in some sense by not removing all references of it from memory (like having some pesky static delegate somewhere or etc, even if it is a sign of smelly code).

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

      @@diadetediotedio6918 That's not a leak, you might be erroneously retaining a memory location for your application, but memory leaks are quite well defined and without a memory leak in the JVM GC, it literally cannot leak, if that is a leak then any runtime static data is always a memory leak which is nonsense, an existing reference you could still access is not a leak, a memory leak must lose all references in the program and thus can only be cleaned up by OS upon termination of the program. (as without that memory reference the program can no longer recognize locate that memory to be manually deleted)

  • @khhnator
    @khhnator 3 місяці тому

    you use Rust
    BA DUM TSSSSS

  • @someon3
    @someon3 3 місяці тому

    Nu uh

  • @sl4633
    @sl4633 4 місяці тому +1

    Use rust instead of cpp

  • @TeofilBejan-lg2rt
    @TeofilBejan-lg2rt 5 місяців тому +1

    You can just use smart pointers and you're done

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  5 місяців тому +1

      well as mentioned in the video, they won't help you with difficult cases. You can't manage gpu memory like that for example

  • @Kyoz
    @Kyoz 5 місяців тому

    🤍

  • @desenhonatorre
    @desenhonatorre 5 місяців тому

    It's funny how nowadays we are slowly going back to procedural programming and leaving OOP

    • @niggacockball7995
      @niggacockball7995 5 місяців тому +1

      yeah function pointers within structs is all you need actually

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

      well it's normal. Procedural is both how people think and also how the computer thinks so idk who is thinking that functional programming is good :))

    • @diadetediotedio6918
      @diadetediotedio6918 5 місяців тому +3

      The limits of your language are really the limits of your world.
      And also, one youtuber is not a representative of "we" (assuming you mean programmers in general) and it certainly is not a representative of something we should be doing by itself, I see comments like this in almost any video where someone is using something even remotely close to what other people used in the past, even if the thing itself evolved in some way, it is surely "funny".

    • @tychoides
      @tychoides 5 місяців тому

      @@lowlevelgamedev9330 I found oop useful in cases where where you are modeling stuff properties and behavior, like video games or controlling devices. But I avoid class polymorphism like inheritance as most hierarchies are just arbitrary design decisions that are often bad decisions. Rust "objects" are ok. Mostly I do procedural even in Python. Functional programming is great for processing data, specially in high level languages. Rust functional features for example are ok. Pure functional languages are not worth the pain, as their obsession with avoiding side-effects and immutability is stupid in practice.

  • @marks_shot
    @marks_shot 5 місяців тому

    cmak