Тёмный

VECTOR/DYNAMIC ARRAY - Making DATA STRUCTURES in C++ 

The Cherno
Подписаться 662 тыс.
Просмотров 163 тыс.
50% 1

Опубликовано:

 

1 окт 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 298   
@TheCherno
@TheCherno 4 года назад
Hope you all enjoyed the video! Have a go at the exercises and implementing some of the features we didn't get to in this video (eg. copy/move constructor + operators for the Vector class). And finally don't forget that the first 1000 people who click the link will get 2 free months of Skillshare Premium: skl.sh/thecherno0820
@khealer
@khealer 4 года назад
You could branch on a if constexpr(std::is_pod::value) and if it is, just memcpy things, otherwise copy construct.
@algorythm4354
@algorythm4354 4 года назад
I am really happy with this video! While you provided the solution, I wish you would have also highlighted the issue of the old allocation: it constructs! Imagine if your class had a Sleep in the constructor, or more realistically, a heap allocation. With out operator new, it would slow you down substantially whenever you wanted to resize your vector. Especially over thousands of items.
@vsevolodnedora7779
@vsevolodnedora7779 3 года назад
Hello! Thank you for the video and for your work! I found that the... outcome of this code depends strongly on the compiler. May I humbly suggest a topic for a video about compilers in more details, which one do you use with what flags and what are the pitfalls or gcc, g++, clang, calng++. I am working in Ubuntu and I found that the only compiler that works for this project is "rustc" that I've never heard of before :)
@sumeetsuryawanshi8384
@sumeetsuryawanshi8384 4 года назад
Bro please don't give up on finishing this series ...u r all I can rely on.🙏
@vitluk
@vitluk 4 года назад
amen
@exodusfivesixfivesix8050
@exodusfivesixfivesix8050 3 года назад
This is literally my first stop before reading text book.
@Nikiux133
@Nikiux133 3 года назад
You still have a bug in ReAlloc function in line 95: newData[i] = std::move(...); - you can't use assignment operator here (either move or copy) because newData[i] is uninitialized memory - it is not the object of type T and by calling operator= (again move or not) you treat it as if it is object of type T. So instead of that you should use placement new once again so change that line to: new (&newData[i]) T(std::move(m_Data[i]));
@Serenity-cr1sw
@Serenity-cr1sw 2 года назад
Thank you man!!!! I am looking for exactly the fix for this issue! The code does not work for std::string, it crashes exactly at this line!! Thank you man I appreciate it!
@triangl3boi
@triangl3boi 2 года назад
Yes, I've noticed that too. I'm mostly going by myself but my ReAllocate function is very similar to this. My constructor for a class allocates some memory but the constructor is not called so when assigning (copy is called) the data is just leftover memory.
@afterlife1578
@afterlife1578 Год назад
he has addressed this issue in the writing an iterator video
@darshanghorpade9590
@darshanghorpade9590 Год назад
hey newBlock is of type T* so I replaced the code you gave, but now its showing Buffer overrun while writing to 'newBlock' error 'Vector3::Vector3(const Vector3 &)': attempting to reference a deleted function
@AlexeiFarWest
@AlexeiFarWest Год назад
It is initialized. When you create your array as "new T[size]" it initializes every element with default constructor. Which is a problem, because what if your value_type doesn't have default constructor? To create uninitialized array you need to use allocator. I also would suggest to use std::construct_at instead of placement new operator. It does the same thing, but more descriptive and easier for an eye.
@supersquare
@supersquare 4 года назад
Would love to see a video on variadic templates someday :)
@donrumata5299
@donrumata5299 4 года назад
With forwarding references...
@donrumata5299
@donrumata5299 4 года назад
Implementing an std::invoke clone
@treyquattro
@treyquattro 4 года назад
I'm guessing you would live to regret it
@PixelThorn
@PixelThorn 4 года назад
Urgh, that...
@enriquellerena4779
@enriquellerena4779 Год назад
We’re still waiting for his Exceptions vid he promised around 4 years ago 😂
@thestarinthesky_
@thestarinthesky_ 4 года назад
Love this topic: Data Structures in C++ . Thank you soooo much .
@Goejii
@Goejii 4 года назад
Recreating the vector class is a good exercise to explore and experiment various useful features of C++
@user-ei1vi
@user-ei1vi 4 года назад
It will be great if you consider to modify your custom vector class to work with range-based "for" loop and show us how
@Beatsbasteln
@Beatsbasteln 4 года назад
i think that's what he meant when he said he'll make a video on iterators
@user-ei1vi
@user-ei1vi 4 года назад
Already figured out how. I have just write begin() and end() methods which returns something acts like iterator, but i done this in custom string class, in vector class it should work the same way.
@joa_joa
@joa_joa 4 года назад
I'm really enjoying these longer C++ videos, keep it up ! and thanks !!
@youcefsb4708
@youcefsb4708 3 года назад
For all those who did make it to 36:05, and then got lost after "HAHA did you think that was it?", Kudos to you.
@sandeepkalluri
@sandeepkalluri 3 года назад
Somebody explain to me
@cavalfou
@cavalfou 3 года назад
​@@sandeepkalluri Essentially, delete operator does 2 things: call dtor, and then free memory. delete[] call dtor of each of its elements, then free memory. The problem is, if we manually call dtor of some item, it will in fact delete its members memory(int* in our Vector3 example), but the Vector3 instance is still physically present in the contiguous array of our Vector instance. That means that if we call the Vector delete[] method, ie when the Vector instance is out of scope in this case, Destructor of each item may be called Twice ! The problematic items here are the one cleared or popped back. When delete[] iterates through items to call dtor and free, it will not stop at our m_Size defined value, but out Clear implem does. If you want to check stuff by yourself, just simply emplace and immediatly pop some object from Vector in debug mode. You can clearly see that in the memory our object is still living after pop. Destructor of an instance manages its member destruction, not the object itself. We have a similar concern with the new operator(although it doesn't cause crashes): it allocate memory, then call ctor. In case of re allocating resource (or "reserving"), we want to make sure we have enough space for our future item to be added. We do not want to actually create default objects waiting to be overwritten by future actual pushed back ones. That is why we use this syntax: ::operator new which only allocate UNINITIALIZED memory, ie memory we own but may contain unpredictable garbage. Hope this helps.
@vintagewander
@vintagewander 3 года назад
​@@sandeepkalluri new calls the allocator to allocate memory, with size of the type you passed in, and then call the constructor to create an object on that memory allocated delete calls the destructor first, and then calls the deallocator to deallocate memory the ::operator new only allocates memory, and it does not construct anything, the memory is now yours, but it has nothing in it, to construct an object of type T in that memory, you have to do something called a placement new new(address) ctor(data) so the normal new operator that you would normally use, it does two things automatically, allocate, then construct in this video, what you're doing is you do those two things by your own the same goes with ::operator delete(ptr, size * sizeof(T)) it only deallocates, and does NOT call the destructor so what the normal delete would do is to call destructor, then call the ::operator delete behind the scenes, the deallocate since in this video, you have a lot of parts that you call the destructor explicitly, and then finally you call the normal delete, which calls the destructor again, despite that it has already been called at some other part of the code if you're sure about calling the destructor exactly where and when you wanted, then all you need is the deallocator And since you can't call ::operator delete on the normal new, you have to also do the two task: allocate by using ::operator new and placement new manually, just so the ::operator delete can work, deallocates what ::operator new has allocated
@krishp4907
@krishp4907 3 года назад
Wow, that gotcha moment at the end was so inconspicuous that I'm a bit shaky in writing efficient C++ code and debugging it. May this series never end for the good of me!
@cm0786
@cm0786 4 года назад
About 2 years ago I really became intrigued by stl. The vector class was the first one I tried recreating. And failed miserable. How ever I have redone this exercise about 20 times since. And I can write a vector class with the majority of the features one would want in about 1 day. I encourage everyone to do this exercise every once in a while. You always learn somethimg new.
@leocarvalho8051
@leocarvalho8051 4 года назад
I am planning on writing my own stl
@theb1rd
@theb1rd 4 года назад
This is a bug: newBlock[i] = std::move(m_Data[i]); "newBlock" is uninitialized memory - calling move assignment method will likely lead to a crash (depending on T). Do this instead, using the move-constructor: new (newBlock + i) T(std::move(m_Data[i]));
@arnaudgranier3045
@arnaudgranier3045 4 года назад
Yes I don't know about you but I get a runtime error with the original code and I ended up with the same conclusion. For some reason, The Cherno does not seem to have this issue...
@theb1rd
@theb1rd 4 года назад
@@arnaudgranier3045 Either the compiler is zeroing the memory for him (which would just happen to work for a lot of objects, if all zeros are a valid state), or he got lucky. A proper debug build would initialize that memory to 0xfefe to shine a light on this bug.
@邓强-r3q
@邓强-r3q 2 месяца назад
The vector3's constructor and move assign function have problems, "m_MemoryBlock"cannot simply assign value(m_MemoryBlock = other.m_MemoryBlock;), if we push back a vector3 value(Vector3 v3(1, 2, 3); vec.push_back(v3); ); it will double free(v3 free once, vec free second)
@邓强-r3q
@邓强-r3q 2 месяца назад
The vector3's constructor and move assign function have problems, "m_MemoryBlock"cannot simply assign value(m_MemoryBlock = other.m_MemoryBlock;), if we push back a vector3 value(Vector3 v3(1, 2, 3); vec.push_back(v3); ); it will double free(v3 free once, vec free second)
@rafalmichalski4893
@rafalmichalski4893 4 года назад
42:48 Is this assignment valid in 96 line (underlined by the way) ? newBlock[i] = std::move(m_Data[i]) It is assignment xvalue object to raw memory. Is it ok ? Shouldn't be placement new again something like that ? new(&newBlock[i]) T(std::move(m_Data[i])) If yes, then maybe your code has UB but did not crash.
@donrumata5299
@donrumata5299 4 года назад
It should be a usual move assignment operator...
@rafalmichalski4893
@rafalmichalski4893 4 года назад
@@donrumata5299 Why ? newBlock is raw memory (like malloc allocated)
@flexw
@flexw 4 года назад
I think it doesn't matter how the memory where the object gets copied looks like. It's just important that there is memory that can be written. The move constructors initialises the memory in the raw area how it needs. Every time a c++ class gets allocated the constructor writes data into raw memory. The member functions and stuff gets not stored in the allocated memory, if that was your doubt. The allocated memory just holds data and on construction the data is always raw. Hope this helps a bit.
@donrumata5299
@donrumata5299 4 года назад
@@rafalmichalski4893 the idea is that there cannot be a "raw" memory. If you have permission to manipulate it, it doesn't differ from any other memory
@shailist
@shailist 4 года назад
you are correct. the implementation in the video can mess up if you create a vector of a class with virtual methods, since the vtable pointer of the object won't be initialized.
@rodrigoroaduterte9415
@rodrigoroaduterte9415 11 дней назад
I hope very much that the std::vector is NOT written like that (17:20) because downsizing without deleting (calling destructors) of excessive vector elements is a direct path to a memory leak.
@svenbtb
@svenbtb Год назад
I'm getting a problem with PopBack. My editor/compiler isn't seeing 'T' as something valid within the scope of the function, and as such when I try to call the destructor on T, the next time that it tries to print the value from my Vector it's printing garbage (negative infinity). not sure what's wrong or how to fix this, I went back to the part in the video but couldn't figure out what I could have done wrong, and I'm not sure what to search for to figure out how to fix it my code, for reference: void PopBack() { if (m_Size > 0) { m_Size--; m_Data[m_Size].~T(); } }
@gonpaul
@gonpaul Месяц назад
It is cool content! Thank you very much, Cherno!!! Like pressed! One thing I wish the vid had is a link to a git repo with code. Though, I am coding the data structure along with you, some place to look up code would not hinder (for educational purposes) 🤠
@tannerbarcelos6880
@tannerbarcelos6880 4 года назад
Learning data structures in c++ makes it much easier to understand and do in other languages. C++ was the language used in my comp sci program for intro to computer sci and for data structures and algorithms and now I’m doing data structures and algorithms in JavaScript preparing for interviews and that foundation in c++ helps a ton. If anyone is a student and has to do c++ in school, don’t be overwhelmed. Trust the process, work hard, and you’ll do just find. Cherno clutch yet again with perfect quality content!
@koonhanong2267
@koonhanong2267 Год назад
42:06 line 98-99 calling the destructor on m_Size works if newCapacity >= m_Size. But if newCapacity < m_Size, you might miss out destructing some objects in m_Data?
@WotJOfficial
@WotJOfficial 3 месяца назад
cant get the variadic emplaceBack function to work at all, with or without std::forward. its exactly how you have it in the video, too. might be because im using Clang instead of MSVC. it throws an error about "Excess elements", which i guess means its not going through more than one.
@RyanSmith-1978
@RyanSmith-1978 7 месяцев назад
Anyone know why I am getting Copy Destroy twice before the 'Copy Copy Destroy Destroy Copy Destroy'? In debugging each time it pushes back a new object, Copy and Destroy get printed, so why is there only one showing in the video even though 2 objects are pushed back? Thanks.
@Brad_Script
@Brad_Script 2 месяца назад
ReAlloc shouldn't be doing deep copies (it should only be moving the data) so I don't understand why memcpy wouldn't be appropriate in this case
@dmytroboiko1
@dmytroboiko1 9 месяцев назад
I did my own implementation using std::move(), it works fine on reallocating, but only in the release mode, and crashes with "heap corrupted" error in the debug mode.
@snookiewozo
@snookiewozo 4 года назад
"Hopefully bug-free" yup, try using it with std::string
@Albert-px4jo
@Albert-px4jo 3 года назад
Yeah. How to resolve if the template argument is std::string, the program still crash
@betterfly7398
@betterfly7398 3 года назад
hmm, why would it? std::string is responsible for it's own allocations and deallocations, and as long as the vector doesn't call the destructor twice, then it wouldn't.
@Mr.Freemen_G
@Mr.Freemen_G 5 месяцев назад
Спасибо тебе! Для начинающего трудно, но очень интересно! Хотя предыдущее видео понятнее про массивы.... Спасибо!
@karamu451
@karamu451 3 года назад
If anyone else is confused to why std::string isn't working, my understanding is that in the PushBack function or wherever you're setting values in m_Data you actually need to placement new the object into place not use the assignment operator here. Basically you'll wanna replace m_Data[INDEX] = newValue; TO new(&m_Data[INDEX]) newValue I'm fresh to this idea so if anyone has a better description of why, it'd be much appreciated. Thanks!
@carsten.svanholm
@carsten.svanholm 2 года назад
Try this void PushBack(T&& value) { if (m_Size >= m_Capacity) Realloc(m_Capacity + m_Capacity / 2); new(&m_Data[m_Size]) T(std::move(value)); m_Size++; }
@darshitnasit3130
@darshitnasit3130 4 года назад
I have added more constructors which takes arguments as initializer_list : 1. Vector(const std::initializer_list&); 2. Vector(std::initializer_list&&); Then I have created a Student class and created three objects of it s1,s2,s3 And then I try to do following: Vectorstudents = { s1, s2, s3}; Vectornumbers = { 1,2,3,4,5,6,7,8,9 }; So as I am passing s1,s2,s3 as "lvalues" for students and 1,2,3,... as "rvalues" for numbers. But in both of cases it is calling 2nd constructor. So why Vectorstudents also calling 2nd constructor? Can you help me ?
@hobajt
@hobajt 4 года назад
I think it's because in both cases you're still initializing the vector with temporary instance of initializer_list (so r-value). If you want to call the l-value constructor, you'd have to do something like: std::initializer_list list = { s1,s2,s3 }; Vector students = list;
@PrinceGupta-jo8lo
@PrinceGupta-jo8lo 4 года назад
The inplace new and operator new/delete part was new to me, and really amazing. I knew I'll learn something new from your video.
@КостяКиндалюк
@КостяКиндалюк Год назад
I didn't understand one thing... How should you implement the destruction of allocated structs or pointers?
@5ko99
@5ko99 3 года назад
I think there is a bug in reallocate function. If we enter in that if statement : if (new_capacity < m_size) m_size = new_capacity; then I think in for loop when we call destructor of each element, then if old m_size is bigger then new m_size then I think we do not call destructors of all elements. Correct me if I'm wrong. Great job btw :)
@tri--
@tri-- 2 года назад
Yeah, that's true. This is very scary because it can lead to memory leaks if the T object is supposed to free some memory in the destructor.
@xtriangleboi
@xtriangleboi Год назад
Possible fix: At the start, save the current size. After the loop, enter in a new loop starting from the current size till the previous size. Then call destructors for those.
@darshanghorpade9590
@darshanghorpade9590 Год назад
hey Cherno, please add set class implementation using template, I am stuck at iterator logic implementation
@UsernameUsername0000
@UsernameUsername0000 Год назад
Would setting all pointers to heap memory in the destructors to nullptr also solve the problem at the end of the video?
@soniablanche5672
@soniablanche5672 8 месяцев назад
realloc might actually not do copies if your lucky and only grow the size of the array
@yugansharora3787
@yugansharora3787 3 года назад
At 19:40 what did he mean like what should we do can anyone tell me pls I'm not experienced in advanced stuff
@VivekYadav-ds8oz
@VivekYadav-ds8oz 3 года назад
But what if you call Clear() on the object, and then when the object goes out of scope, its destructor calls Clear() too, leading to the same error again?
@stahoviak
@stahoviak 6 месяцев назад
When calling "T* new_block = ::operator new(new_capacity * sizeof(T));", I get a "new_block" that is only 8 bytes in length, i.e. "sizeof(new_block) == 8". Since our "Vector3" type is 32 bytes in length, I even tried being explicit about it and doing "T* new_block = ::operator new(64);" (allocating space for 2 Vector3 elements on first reallocation) just to help me debug. But even for that call, I still get a "new_block" that is 8 bytes long. Am I doing something wrong when calling ::operator new()? Anyone have any idea why I'm getting the same size allocation regardless of what I pass to ::operator new()? Should we be using ::operator new[]() instead?
@Brad_Script
@Brad_Script 2 месяца назад
new_block is a pointer, when you do sizeof(pointer) you will get 4 for 32bit program or 8 for 64bit program
@supersquare
@supersquare 4 года назад
Thank you so much Cherno, this video is absolutely phenomenal
@shrivatsankchari1729
@shrivatsankchari1729 2 года назад
completely lost after 15 mins lol
@tunech69
@tunech69 Год назад
Hi @TheCherno, there is a slight issue in your Clear() function. You probably know about it, but i will mention is anyways because there is no mention in the video and it took me a couple of hours to solve it. (Yes i have watched Iterators video, but this issue was not solved (maybe im wrong) there). Clear function does not release memory allocated for m_Data, it only calls for destrustors. In order for Clear function to work properly, it need to look like this: void Clear() { for (size_t i = 0; i < m_Size; i++) { m_Data[i].~T(); //calling all the destructors. } ::operator delete(m_Data, m_Capacity * sizeof(T)); // releasing memory, also, wouldnt this call also call each destrustor? Im not sure, maybe you can check it. m_Data = nullptr; // this one is important, because if we call Clear second time right after first call, without allocating new block of memory, there will be a memory access violation m_Size = 0; m_Capacity = 0; //can be 2 if ReAlloc does not fix bug, where if capacity is 0 vector can not grow. }
@xtriangleboi
@xtriangleboi Год назад
Clear is not supposed to release the memory, it is just a function that's supposed to remove all elements from the vector. The m_Data buffer should be left like how it is because we may and will probably still work on the vector after calling Clear on it. We only release the memory whenever we want to destruct the vector object. This idea is the exact same with std::vector or many other vectors. EDIT: Also placement delete doesn't call destructors.
@HattoriHanzo031
@HattoriHanzo031 3 года назад
Great video! It looks to me that there is a potential memory leak in ReAlloc function if new capacity is smaller than size, Desctructors will be called only on first newCapacity elements, or am I missing something?
@gunrunjk
@gunrunjk Год назад
Thanks for your video, I really enjoy all your series. I have a question about T* newBlock = new T[newCapacity]. when it declared, why it shouldn't be deleted like the "delete[] newBlock" after "m_Capacity=newCapacity"?? Is that not leaking a memory ? if you do pushbacks 100 times, newBlock would stay 100 memory blocks in memory , am I incorrect? Please teach me.
@xtriangleboi
@xtriangleboi Год назад
m_Data gets set to newBlock, so if you delete newBlock, you essentially delete m_Data, which is a big no no. You only need to delete the old data (m_Data) before you set m_Data to newBlock. After that both newBlock and m_Data point to the same memory address.
@colinmaharaj
@colinmaharaj Год назад
Can I write a templated dynamic array that can be saved to and loaded from disk?
@Noah-357
@Noah-357 2 года назад
" std::" to be written in every line and every word makes me confused and makes the code really complicated in how to read it. My eyes are literally on "std::" instead of looking on what the code does. When I try to understand my professor code, I literally delete the "std::" and put instead names space std;. Also, I organize the messy code because he also write the function like this Void Function{Data}cout
@xtriangleboi
@xtriangleboi Год назад
If you keep doing this on a large-scale project, essentially the compiler will get very mad at you. Another library you use may have a function like move. Imagine you did using namespace on both, the compiler wouldn't know which one to call. For little projects, it should be relatively OK to do using namespace std, but on medium to large scale projects, it is a big no no. And don't ever do "using namespace std" in header files, never ever.
@bassbatterer
@bassbatterer 4 года назад
Funny you put this video up, Just today and yesterday i've been working on my own spin on this.
@shadowmil
@shadowmil 4 года назад
Your ReAlloc function doesn't consider memory alignment
@josefaschwanden1502
@josefaschwanden1502 4 года назад
how so?
@VivekYadav-ds8oz
@VivekYadav-ds8oz 3 года назад
This video inspired me to create a sort of a mish-mash of two data types together, basically a compromise b/w a linked-list and a vector. What if you have moderate-sized arrays that link to each other? Array[10]->Array[10]->Array[10]->... and so on? i) This way, you don't have to make as many hops for reaching an element. MishMash[35] is actually just two hops away, rather than 35 hops! ii) You still have to allocate a new buffer for every 10 inserts (this could also grow exponentially), but you don't need to copy the old buffer. I feel like this data type can be used for vectors that dramatically alter in size frequently.
@legotecnico
@legotecnico 4 года назад
very interesting video and series really! I have one comment though. In your Vector3 class implementation of the move assignment operator (line 41) I think you should call delete m_MemoryBlock before assigning other.m_MemoryBlock to it, otherwise a memory leak is created. Correct? But then, if you do so, each time you move a Vector3 element to the vector (PushBack of ReAlloc function) you get a memory access violation because you are moving the element to an uninitialized memory block and the delete m_MemoryBlock in Vector3 move assigment fails. To solve that I think it is necessary to initialize to 0 the memory allocated with ::operator new every time this is used, with something like std::memset(m_data, 0, m_capacity * sizeof(T)); In this way the delete is called on a nullptr and does not fail. Am I wrong? Thanks.
@1996robinC
@1996robinC 3 года назад
Yes, you're a lifesaver! I had this exact issue while trying this Vector class out with my own implementation of String, it would indeed crash when calling the move assignment operator was called on non-initialised memory. However I still found a case for a crash: when calling pop_back, my own String deleted its m_Data block but did not set it to nullptr; So when calling push_back again afterwards, the same memory access violation happens. The fix was to memset to zero also on pop_back() and on clear(). Another fix would be to edit my String destructor to set the m_Data to nullptr, but I find it a cleaner solution to do this within Vector. EDIT: he addresses this at the end of the "Writing an iterator in C++" video. The clean solution to fix this issue is with "placement new" construction (like used in emplace_back) instead of the assignment operator.
@shaiavraham2910
@shaiavraham2910 4 года назад
Can you make a video explaining your coding style and naming conventions? I think it would be cool to see a little video about why you prefer PascalCase and prefixes on variables (like m_ and s_) and what are your tips for choosing naming and coding conventions. It would also be cool if you could talk about your C# conventions as well (as far as I know, the m_ prefix isn't very popular in C#, so I think it would be cool to know if you stick to it and why).
@leocarvalho8051
@leocarvalho8051 4 года назад
He once said that he used to use camelCase back when we was doing java but that after sometime at EA he got so much used to PascaCase that he cant use camelCase anymore (sorry bout my english)
@KarolSzapsza
@KarolSzapsza 4 года назад
Choose what do you personally prefer (or make a consensus within the team you are working with). Some IDEs (e.g. CLion or VS w/ReSharper) allow to set preferred naming conventions in Settings and they will underline inconsistently named variables etc. Big companies have some variable naming (and code formatting) standards, you can find them easily, search "Mozilla C++ coding style", "Google C++ Style Guide" etc.
@aquavitale3551
@aquavitale3551 4 года назад
just can't help waiting for rbtree-based set explained by The Cherno
@damnstupidoldidiot8776
@damnstupidoldidiot8776 4 года назад
rbtree-based set gives me PTSD.
@aquavitale3551
@aquavitale3551 4 года назад
@@dominicjung4950 absolutely. deletion is kinda magic, and most of tutorials skip this thing
@damnstupidoldidiot8776
@damnstupidoldidiot8776 4 года назад
@@aquavitale3551 It requires very weird recolouring but you can go on geeksforgeeks it explains it quite well.
@kariakistephen508
@kariakistephen508 2 года назад
Cherno please am a beginner I didn't understand shit
@nezz0r
@nezz0r 3 года назад
Is there a reason why C++ handles the new [] type inconsistent? If you have this: "new SomeClass[size]", the default constructor will be called. If you do this: "new int[size]" (buildin primitive type), there is no pre initializiation. But if you call new int[size]() you will get it. Consider this code: #include class Vector2 { public: float m_x, m_y; Vector2() : m_x(0), m_y(0) {} Vector2(float x, float y) : m_x(x), m_y(y) {} }; int main() { constexpr int size = 5; int* intArray = new int[size]; int* intArray2 = new int[size](); int* intArray3 = (int*)::operator new(size * sizeof(int)); std::cout
@binary_gaming113
@binary_gaming113 4 года назад
Thank you for the great video! Will you do a tutorial on custom allocators some day? There are not really that many tutorials on it.
@martian8817
@martian8817 4 года назад
try implementing vector using the the specifications on cppreference, just by encountering custom allocators in a practical setting actually teaches you a whole lot about them (tip : look up std::allocator_traits first to see how c++17 and on handles allocators. )
@Yupppi
@Yupppi 10 месяцев назад
I tried to figure out an function to do the doubling of the capacity initially, but heavily dampening as the capacity grows, but nothing was really that satisfying. Like it'd always still grow quite a lot once it reached like 500. Which is obviously quite unnecessary as you'll take forever to fill it even if you had that much more data. Or it wouldn't grow a lot in the beginning which is also the opposite of what you'd want to. Without doing if checks for the size, that'd also be the opposite of what we want, building processing cost trying to save it.
@silverqx
@silverqx 4 года назад
new(&m_Data[m_Size]) T(std::forward(args)...); how cools is that 😂 that's awesome 😎 I didn't know that I can invoke new operator like that, thx ✌ By the way, examples like this are the best how to learn and understand how underlying std library works. 👍
@tzimmermann
@tzimmermann 4 года назад
That's called "placement new", and it is indeed really powerful! Have a look at memory pooling and custom allocation, the whole subject is quite interesting.
@jorisbaranauskas9326
@jorisbaranauskas9326 3 года назад
How should I return a range of the vector? Vector getRange(size_t startIndex, size_t count) const { Vector tempVector= Vector(); for (size_t i = startIndex; i < startIndex + count; i++) tempVector.pushBack(std::move(this->itemsArray[i])); return tempVector; // This is wehre it calls "tempVector" destructor } Because it deletes tempVector via destructor and then returns empty vector.
@DonchoGunchev
@DonchoGunchev 3 года назад
You could only have size if you predefined the number of elements you will allocate (2, 4, 8, 16, ....) saving 1 size_t sacrificing performance, no?
2 года назад
1. std::construct_at instead of operator=(T&&) in emplace (Edit: after some research I discovered std::construct_at is introduced in c++20, for c++17 and below, new() must be used) 2. you violated rule of 0/3/5 implement those ctors/ops! (TIL I learned there was a malloc/free counterpart in c++ in the form of ::operetor new/delete)
@BohemianDoor
@BohemianDoor 3 года назад
Getting an segmentation violation signal in the push_back function and have no idea why. All i'm getting is that is is caused by a READ memory access, which is m_Data[m_size] = value;
@crisdellani
@crisdellani 4 года назад
After all the fame, the fact that you keep this C++ series for dummies like me going, is amazing! The game engine series is way over my head and the reaction videos are not really my thing.. but I do hope that you are getting all the compen$ation you want because you deserve it... kuddos mate
@ohwow2074
@ohwow2074 3 года назад
After seeing this, I feel I am as powerful as the Nazi army in 1939 lol. But of course double the pride, double the fall...
@jenishmonpara
@jenishmonpara 3 года назад
Video is very good. But could have been better if background music volume was kept lower. Its a bit of extra effort to separate your voice. Thanks
@ninjamonkey4135
@ninjamonkey4135 2 года назад
adding a constructor for std::initializer_list and a deduction guide would be good too. Then we can just "Vector myVect { t, t, t, ...};".
@user-hz4tc2pf3x
@user-hz4tc2pf3x 4 года назад
0:25 Okay I can't take 4 dimensions anymore. I need to see how it looks. So I'm going to challenge you to create a 4D renderer. (I think it's suitable because you like graphics programming the most, correct me if I'm wrong.)
@algorythm4354
@algorythm4354 4 года назад
Not all the dimensions need to refer to physical dimensions. The fourth dimension is usually time ;)
@notpipa_
@notpipa_ 4 года назад
Great video! Do you plan to do some algorithms like breadth first search in the future?
@slobodanstajic652
@slobodanstajic652 3 года назад
yeah, its official- im too stupid for this. i just have to make peace with the fact that I belong in the broad category of people whose dreams dont come true.
@koungmeng
@koungmeng 3 года назад
Thanks, mate! I really learned a lot from making my own version of the STL vector.
@MrBlawkEyes
@MrBlawkEyes Год назад
40:13 Constructors are being called there if you do a cout in your constructors you will see them print. But I assume the point being that they don't need to be called so thats why we switch to an operator new.
@pseudounknow5559
@pseudounknow5559 3 года назад
Does someone have the code written in this video ?
@PedroOliveira-sl6nw
@PedroOliveira-sl6nw 4 года назад
I was halfway happy that I had done pretty much the same and then I realized he was going to implement a lot of the vector interface :D
@andreasenglert1723
@andreasenglert1723 Год назад
Thx for the video. How did you do, what you did at 22:14? (initializer list without typing)
@vunderstudios
@vunderstudios 2 года назад
an optimization that i use in my game engine array class, is using type traits to check if T is a POD, and if so using memcpy (not memmove for performance) to copy elements instead of using std move. compilers may notice this, but i added it just in case
@nailbomb420
@nailbomb420 4 года назад
off topic, but does anyone know what theme Cherno uses? I find the oranges and other colours quite appealing but haven't been able to find a match.
@footballfactory8797
@footballfactory8797 4 года назад
I have no idea wtf is happening here 🤣
@justwatchingstuff1507
@justwatchingstuff1507 2 года назад
I don't know if you read all your comments but I just wanted to say I really am liking you breaking things down!
@VineetNairhero
@VineetNairhero 4 года назад
Saw this live😎
@matteocampo1732
@matteocampo1732 4 года назад
Me too :D
@funhuninjastudio
@funhuninjastudio 4 года назад
Same
@elirannissani914
@elirannissani914 4 года назад
Me 2 :)
@blazingazong
@blazingazong Год назад
Stack allocated vector that is actually just a single node in a linked list. Every so often you get a slower step, but I am so intrigued to try implementing it
@GeekyMino
@GeekyMino 4 года назад
I really enjoy watching your videos! Keep up the good work!
@reedsdevine336
@reedsdevine336 2 года назад
Since We're big boys here... 8:25 It cheered up my dull day, thanx cherno
@sanjeevsaharan
@sanjeevsaharan 4 года назад
Doesn't assignment operator will be called while push back instead of copy ?
@afterlife1578
@afterlife1578 Год назад
for anyone getting a bug for making a string vector, he has addressed the issue in the writing an iterator video.
@AspiringRider
@AspiringRider 9 месяцев назад
I still don't understand how size can become greater than capacity. As soon as it becomes equal we are allocating new memory and hence it can be either less than capacity or equal to capacity in case of push back operation as we do not push more than one item. Does any one have any idea?
@aleksandarfranc1094
@aleksandarfranc1094 2 года назад
Anyone know why this line of code at the end of tutorial will not work: Vector vector; vector.PushBack("aca"); ?
@aleksandarfranc1094
@aleksandarfranc1094 2 года назад
PushingBack string seams not to work after adding ::operator delete and new.
@carsten.svanholm
@carsten.svanholm 2 года назад
Replace this line m_Data[m_Size] = std::move(value); with new(&m_Data[m_Size]) T(std::move(value)); void PushBack(T&& value) { if (m_Size >= m_Capacity) Realloc(m_Capacity + m_Capacity / 2); new(&m_Data[m_Size]) T(std::move(value)); m_Size++; }
@aleksandarfranc1094
@aleksandarfranc1094 2 года назад
Will try it!
@TopConductor
@TopConductor 4 года назад
is this code available to check somewhere? I haven't quite understood the last part with delete with non trivial data types and variadic templates thing.
@joaopedrovoga5497
@joaopedrovoga5497 2 года назад
This was harder than I expected.
@kfossa344
@kfossa344 4 года назад
Don’t know the first thing about any of this but here I am.
@appleuser4627
@appleuser4627 3 года назад
Well done bro, full support from India. And thank you for amazing advanced tip.
@foomoo1088
@foomoo1088 2 года назад
Very cool! I think I “know it all already” but usually learn something new in these! I’m writing my own containers now for my personal engine project and great to get some ideas from The Cherno 😀
@foomoo1088
@foomoo1088 2 года назад
Also might need to check for “self” in your “moves”
@Diego-Garcia
@Diego-Garcia 10 месяцев назад
Holy, C++ is complex as duck! Now I understand why Linus doesn't want it in the Linux kernel. Imagine debugging a code with this complexity that wasn't made by you. The implicit things you need to be aware of...
@ianpan0102
@ianpan0102 4 года назад
Would love to see a video on creating class String from scratch!
@z2ken
@z2ken 3 года назад
if does not work for T is type of "std::string". how can i make it ?
@shreksthongg
@shreksthongg 4 года назад
This is very strange timing because I just coded my own version of a vector class a few days ago. I'm curious how much different my implementation was from yours
@martian8817
@martian8817 4 года назад
Same, the Array episode inspired me to start a mystl project which I've been having some fun with.
@ATeima-kk5ps
@ATeima-kk5ps 4 года назад
Yeah, me too. I'm going to dive into the video now
@augustin7105
@augustin7105 4 года назад
Now I have an excuse to sleep.. Data Strucure..
@wutoby1052
@wutoby1052 3 года назад
Check out the time 22:32, Only four "copy" get printed to the console, which made me confused, I think there should be five "copy", three of them from the right value when creating those three Vector3 objs, the other two “copy” are from ReAlloc when the vector's size increase from 2 to 3, then I realized in Cherno's video, the information printed may not be complete, so indeed five copies should be printed, am I right?
@wutoby1052
@wutoby1052 3 года назад
Still not sure why only four "Copy" get printed, not five
@TimCrinion-j2r
@TimCrinion-j2r 10 месяцев назад
34:00 If we use "new", don't we need to have a "delete" somewhere too? To avoid memory leak?
@masheroz
@masheroz 3 года назад
If you used realloc to make the allocation smaller, aren't you then leaking memory by forgetting the array contents you're now making out of range?
@masheroz
@masheroz 3 года назад
No. as you're copy/moving the elements to a new block of data, and then deleting the original data.
@browaddup3289
@browaddup3289 3 года назад
I would love to see you implement a dictionary :)
@sukivirus
@sukivirus 4 года назад
Why not use smart pointers inside your vector class?
@lancelotxavier9084
@lancelotxavier9084 4 года назад
Visual Studio is free. Backend is powerful, but the front end user interface is archaic.
@bulentgercek
@bulentgercek 3 года назад
What :D Its the best. You must be from future.
@aleksandarfranc1094
@aleksandarfranc1094 3 года назад
Why, in ReAlloc function if we instead of this code line: T* newBlock = (T*) ::operator new(newCapacity*sizeof(T)); write this code line: T* newBlock = new T[newCapacity]; Then at this code line: ::operator delete(m_Data, newCapacity * sizeof(T)); We get error, exception throw.
Далее
ITERATORS in C++
17:09
Просмотров 208 тыс.
Stop using std::vector wrong
23:14
Просмотров 65 тыс.
ВЫЗВАЛ ЗЛОГО СОНИКА #Shorts
00:38
Просмотров 58 тыс.
ARRAY - Making DATA STRUCTURES in C++
23:19
Просмотров 111 тыс.
All about MEMORY // Code Review
33:42
Просмотров 165 тыс.
I Rewrote This Entire Main File // Code Review
16:08
Просмотров 159 тыс.
Stack vs Heap Memory in C++
19:31
Просмотров 570 тыс.
31 nooby C++ habits you need to ditch
16:18
Просмотров 789 тыс.
Weak Pointers in C++ (std::weak_ptr)
17:25
Просмотров 50 тыс.
Understanding C++ Vector (Dynamic Arrays)
1:14:34
Просмотров 22 тыс.
Constructors Are Broken
18:16
Просмотров 108 тыс.