Finally solve memory leaks in C++!

preview_player
Показать описание
In this video, I will show you how I deal with memory allocation in C++ so I never have leaks, and I don't even stress about it!

#cpp #gamedevelopment #programming

Full guide about pointers 👉💪:

Join my Discord 🤖:

Try My Game Midnight Arrow 🤩:

Join this channel if you want to support me 😻:

Music: Evan King - Everything is Okay
Music: Evan King - Spicy Boom
Music: Evan King - Pocket Universe
Рекомендации по теме
Комментарии
Автор

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!

lolcat
Автор

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

toksic
Автор

that's the neat part: you don't

darkfllame
Автор

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!

onur_yas
Автор

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.

Lelende
Автор

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.

sledgex
Автор

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

rayboblio
Автор

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<unsigned char> 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.

sledgex
Автор

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.

sledgex
Автор

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

mr.hashundredsofprivatepla
Автор

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

BaDitO
Автор

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.

furuthebat
Автор

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.

sealsharp
Автор

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.

vxcute
Автор

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

legendcat
Автор

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.

Spartan
Автор

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

TheShmupExperiment
Автор

How do you feel about manual memory management?

jasoniswrongabouteverythin
Автор

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

TheBypasser
Автор

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!

thefoxguy