Hey, I just watched this video after std::array and you contradicted yourself. Maybe because you didn't know it when you created this video but in this one you say there's an overhead due to size() but in std:: array video you pointed out that it's a template and does not add any overhead as it simply returns the value. Just wanted to make sure people watching this know that you actually recommended using std::array over c-style array due to many advantages.
Part of what makes you a great programmer/teacher is that you have a deep technical understanding of how all of this works, and you're not afraid to share that information even though it may seem intimidating.
TH-cam C++ videos are like looking up a word in a dictionary and the definition is full of words you don't understand so you look up those words and the chain continues. AAAAARRRGGHH!!!!!!! *slams head on desk*
Bruuuuh. I know this was 2 years ago but I'm going through the same thing. I'm always checking the comments to see if people understand and surprisingly, they seem to. But maaaan!!!
@@mwenge6355 I understand almost all of his videos, the reason is that I've been programming for almost 10 years now, so my advise is to practice video by video and look up some written docs of the same concept that you didn't understand from the video. good luck
this is actually part 30 of a series. theres a 106 episode playlist. the people who are getting it have been watching from the begining. you see a lot of people be confused in the virtual functions video because he introduces new concepts without eplaining them (virtual destructors, -> operator, new keyword, heap vs stack) but he has videos on all 4 of them so when you get to that video, you branch out and watch those 4 videos and then come back and you get everything
You have made me finally UNDERSTAND pointers PROPERLY. I see their potential now. Its just you accessing memory locations and playing around with either those locations or the values in those locations. That is all pointers are !! They are not doing anything weird. Smh. Thanks man. You have no idea how clear this has made things for me. Makes we actually want to learn Machine/Assembly Language
Dude, phenomenal video. Love the technicality (pointer arithmetic (assembly OFFSET), heap alloc/dealloc, little endian, constexpr, c++11 arrays, etc)... great stuff
I'm absolutely loving this series, you should extend this series with a playlist on DSA, Arrays, LinkedList Stacks Queues BST Heaps, and then perhaps different types of algs, sorting and graphing algs
5:16 Actually, less than or equal to is not performed separately, as (less than OR equal to) is the opposite of greater than, and vice versa. However, the code is more readable and more understandable if you write for (int i = 0; i < SIZE; i++) instead of for (int i = 0; i
@Ebola Virus It may depend on how the emitted code is structured. In a very typical for loop you're counting up to some limiting factor so at the bottom of the loop you do the test and jump back to the top if the counting variable is less than the compared value. However, this is very dependent on a) the code that the programmer wrote (obviously) and b) how the compiler, optimizer and code emitter organize the object code. In the x86 world JNL is an alias for JGE (jump if greater or equal). These conditional jump instructions test flags in the flags register to determine whether to jump or not. They can test multiple flags simultaneously, such as the O(verflow) and S(ign) flags in the case of JL/JNL If you wrote *for (int i = 0; i < 5; i++)* then I'd expect the compiler to emit something like: for_loop: . . mov rax, [esp-8] ; i add rax,1 mov [esp-8],rax ; changes no flags cmp rax, 5 ; sets CF,OF,SF,ZF,PF,AF flags jl for_loop ; jump if SF != OF nop In the case of *i < 5* the Sign Flag will be set but the Overflow Flag won't be and the jump will be taken. In the case of *i == 5* (the terminating condition) both the Sign Flag and Overflow Flag will be reset and the jump won't be taken and the CPU will continue at the NOP in this case. There's nothing stopping you writing code like this: loop_top: mov rax,[esp-8] ; i inc rax ; adds 1 mov [esp-8],rax cmp rax,5 jl loop_body jmp somewhere_else loop_body: ; do something jmp loop_top This is slightly less efficient, but the compiler (or hand-written assembler) might produce that kind of structure depending on size of code blocks, processor mode, etc. (in the "old days"(8/16-bit code), a conditional jump could only move the instruction pointer by -126/+129 so you'd have to reverse the sense of the conditional jump and use an immediate 16-bit jump e.g. if the loop code was longer than the distance allowed in the relative conditional jump. The only issue in the video was that Yan incorrectly said that writing e.g. *i
@@treyquattro Modern compilers won't emit a JL or JLE instruction, it will convert it into a JE instruction and compare it to 5 in this case to terminate the loop. Which makes sense considering it's just an XOR that has to be 0 as a result. Whereas if you use a JL or god forbid a JLE instruction it's a bitflip + 2s complement of the second value followed by an addition and subsequent interpretation of the result as a negative or positive number. If you compare sizes and whatnot it actually needs a lot more cycles to do so a modern compiler will omit that instruction. Check Godbolt if you doubt me.
@@Finkelfunk it's up to the compiler and optimizer how it organizes code - what tests and jumps it makes. There may well be optimizations to be made in the arrangements of what conditions to check, but etiher way a jump is going to be made either when the final condition is reached, or when an intermediate condition happens, depending on how the compiler has decided to lay out the code. The issue is that whether the compiler decides to emit JE, JL, JLE or something else (you may see aliases such as JC or JNAE for JB e.g.), the instruction timing is going to be identical - it's a test of a flag and a jump or not on result. Different flags get tested by different instructions but all Jcc (jump on condition code) operations (x86_64) have the same timing for the same sized operands. Saying check it on Godbolt is not very helpful because there are tens of different compilers on Godbolt, each with a variety of optimization settings. What gets generated differs from compiler to compiler, and version to version, and depending on the optimization levels chosen. The original issue was that it was mistakenly asserted that a
So to summarize: Arrays store values of one type together The Array Name by itself is a memory address Arrays can be indexed through both for loops and pointer arithmetic Arrays can be made dynamically or statically (on the stack or the heap)
You're more than a teacher you're a perfect explainer. I wish if there's more like you or as good as you. I've been watching your series from last night and I'm just stuck on your channel. That's awesome.
you are the best so far in my experience of learning online. In my perspective, you don't share knowledge, but rather EXPERIENCE. I am gonna now watch all the c++ experiences taught by you. Thank you soooo much.
6:14 just a small correction for the great video, usually the C/C++ runtime knows the size of the arrays (malloc/realloc... other functions) and of course the operating system as well see VirtualAlloc, HeapAlloc, ... on Windows and even on windows the way it's kept differs between the type of allocators which are used (small/medium/large pool allocation)
4 ปีที่แล้ว +3
Please consider making C# videos..! The way you teach, express things is just amazing. I feel like I don't understand other people's teachings.
At 16:13 you say "you have to mark it as STATIC". Why doesn't the CONST meen it is known at compile time (if it is constant), why the STATIC as well? You are easily the best C++ teacher I have seen, and your videos are perfect in style and content.
@Peterolen Yea. because there is no 'readonly' in C++ like it is in C#. There const means compile time const and 'readonly' means that it can be modified in the constructor.
@@vighnesh153 I think the C++ spec recommends to use constexpr instead of const as const is more used as "readonly" now (or I might be mistaken maybe it was someone else lol)
the const keyword is not necessarily known at compile time. It just means it can't be changed once it's initialized. For instance you can have the following: int i; std::cin >> i; const int x = i; and it is perfectly valid though the value isn't known at compile time. Therefore the compiler would have no way to know how much memory to set aside if you did int MyArray[x] Whereas constexpr or const static both must have constant values that are known at compile time.
These are some of the most useful programming videos on the internet because of your teaching style and structure. First thing that makes you a cut above the rest, is because you cut straight through the bullshit. ie: A variable type is actually nothing special. ie: an array is actually just a small stack of variables, and is sort of actually nothing special. Second thing: The memory viewer. Mind blown! For as long as I've been trying to learn these concepts (and bowing before variable types with a cult like religious reverence), I haven't found any instructor that actually does this. Instead every tutorial or course (I've taken) leaves this sort of thick fog between memory and what we're trying to achieve. As if memory is this magical thing we must never look upon or speak the name of, except in anything but convoluted riddles. Even in my Computer Science 104 course in college they taught us the hardware concepts of memory on the whiteboard, but never even attempted to connect it's fundamental truths to the code side of things. Makes me feel like Memory viewing should really be a part of the introduction, instead of being left only until advanced concepts.
Playing with addressable LED's with an arduino, Ive seen some weird things going on when I accidentally misuse an array. I had no idea what was going on, LED's doing strange things. I did work out that arrays still try to work, I assumed it just used the memory as if it was bigger. Got some cool effects from it. I look forward to the spin offs as you say :)
I started playing with arrays, just to remember how it works and found out that you can change a private atribute of a class (even out side of its scope) using pointers, nice >
16:14 As the size variable should be known at compile time, you've stated that it should be static const (or constexpr). It can also be declared in a #define statement, and easily remembered, like in #define ARRAY_SIZE 5 int example[ARRAY_SIZE];
Yes, that's exactly what I'm thinking about. Is it okay to write macros in-line with your code? Or is it better to just put all the macros on top of the soruce code?
oh no bro macros are evil (because they literally just replace text in your code) avoid them at all possible costs, use them only if it's absolutely necessary
Let just say I just wanted to learn pointers here and I watched 30 videos. And I learned 10 different things and now I'm excited I learned something new and I'm sure I'll watch all the videos.
Hey The Cherno, every so often i see you doing some fancy keyboard combo magic which resembles VIM operations like selecting chunks of code quickly, moving line up or down, duplicating etc. I'd be pretty interested in learning how you've set that up and knowing more about your input "workflow". If you've already done a video on this please link me :)
15:15 the sizeof(pointer) for Visual C/C++ will allways be equal to sizeof(int), because these should be equal to the size of the registers are used in order to not create bottlenecks in CPU operations => the sizeof(pointer)/sizeof(int) will always be 1 for VCRT
Me: Struggling to get the element count of a heap allocated array and failing miserably. The Cherno: It's not really possible in C++*. Me: Suddenly feeling less incapable.
That's a proper "I invoke UB because I don't care about my code". Nobody sane in the industry would ever deliberately invoke undefined behavior, that assignment might as well make your PC order pizza for you.
for using the value of std::array::size() in for loops, you've got to change the data type to signed integer or either declare the variable for the initial value as an unsigned integer
the "perfect" solution would probably be to use size_t for the type of the iterating variable, because by definition size_t "can store the maximum size of a theoretically possible object of any type (including array)" also, you can just do a ranged for over the array if it is only the elements that you need
3:23 Hey! It's not a pointer. An array will be implicitly converted into a pointer to its first element, but it's not a pointer. Pointers store address, and arrays store their elements, so they're definitely different types. If you get the address of a pointer (`&ptr`), the result is a pointer to the pointer; in the other hand, if you get the address of an array, the result is a pointer to the array. As what you saw, in the memory, there are five integers instead of a "base address".
Another reason to allocate on the heap is when you don't know at compile time how big you need your array to be (e.g., an array whose size is determined by user input).
5:23 I checked the compiler explorer and it is in fact not correct that it will do a less than and equals comparison. Basically, compiler magic and all that optimizes it away, so no matter how you write it, it always uses a "je" instruction. But it is definitely more readable to anybody working with your code.
Personal Notes: - there is no array index check in c++ - Pointer arithmetics is done automatically according to the type the pointer points to ( ex: int arr[5]; *(arr+2) accesses the 2nd element) - Stack: int arr[5]; heap: int* arr = new int[5] - Why would i need dynamic allocation? One simple example is to be able to return an array defined inside a function - Since C++17, std::array has been introduced which does bounds checking and knows its size - Didn’t get why array size must be declared as static const at 16:15
I'm leaving this here in case anyone still has any questions. - Using a const variable to specify the size of an array inside a class is not allowed because arrays must have a size that is known at compile-time. - The size of an array must be a constant expression, meaning it must be able to be evaluated at compile-time, so that the compiler knows how much memory to allocate for the array. - On the other hand, const variables inside a class can only be initialized with a value that can be evaluated at runtime. - This is because the value of a const variable inside a class is not known until the object is constructed, which is too late to specify the size of an array. - In order to use a const variable to specify the size of an array inside a class, you should use a static const variable. - This is because static const variables are shared by all objects of a class, so their value is known at compile-time. - Another benefit from doing this is that you use a non-static const int to set the size of the array, each object will have its own copy of the size, which is wasteful and unnecessary. -By using a static const int instead, the size of the array will be shared among all objects of the class and will have a single storage location in memory If you have any confusion regarding what static and non-static is please refer to Cherno's video on the topic
Most funny things do happen, if your index variable lies nearby your array in the memory. Suddenly you start to overwrite the index with some value, which belongs into the array. If that happens in a loop, you will, perhaps, never be able to leave this array-hell. That happend to my team-leader in a real-time, safety regarding, embedded project.
If for example I have dynamic array of class instances that all need to call destructor, because class contains a pointer, when I call delete[]array will it call destructor for each one instance or do I need to do it separately before calling delete[]?
15:19 int count = sizeof(example) / sizeof(int) ------This does not give us zero; the result of this is : 2 int count = sizeof(*example) / sizeof(int[5]);-----This gives zero
There are also std::size() and std::ssize() to retrieve the size (or count of elements) of a raw array (although they work for standard arrays as well), I don't know if these methods were there by the time this video was made but if I'm not wrong they seem to be the safe way to do it now.
It's called garbage collector. It takes care of deleting objects for you. There might be way to take care of deleting your objects yourself. Not sure, i'm not java expert, but there is no reason really to do it in Java. If you really need the performance gain from dynamic memory allocation, Java isn't right tool to use, C++ is.
8:15 what exacty are we adding to the ptr (ptr+2) , does it mean move forward two the size of the TYPE int which is 8 bytes ? ... i know what example[2] means, but ptr +2 !!
5:22 This will probably not be a performance hit. Almost all common ISAs have a single instruction for "jump if less than or equals" that takes the same number of cycles as "jump if less than". (In hardware, the addition of the "equals" check likely has almost no impact on the critical path, since both the less than and equals checks can be done in parallel and the combination is a simple OR)
Couldn't you also specify a set of values when you create the array rather than use a for loop to define their values? For example int myArray[5] = {1, 2, 3, 4, 5}; It would be more efficient to use a for loop if you have a large array, but if there are only a few elements it's quicker to write it this way in one line than to write an entire for loop imo.
So I googled how to find the size of an array because I needed it for a code I was working (note, I'm very much still a beginner when it comes to coding), and while one of the methods was that method you showed of doing arrSize = sizeof(arr) / sizeof(value), another way which was mentioned was this way that I prefer but don't fully understand which uses pointers. The code for this is arrSize = *(&arr + 1) - arr. I didn't use this inside of a function, but my guess is it would still work inside of a function considering that it uses pointers and addresses of. Like I said, I don't fully understand the code, only that it works for finding the size of the array, so if anyone could explain it in detail, I know how pointers work, and I know about addresses of, I just don't understand this specific way of finding the size of an array.
15:15 sizeof(int) is 4 bytes so you'd end up with 1? Were you reading your own comment while saying this or am I missing something?
Lol yeah imma blame that on the jet lag... it would be 4 / 4 which is 1. Still not the size of the array though so the point still stands. :)
@@TheCherno dont need to be smart to understand that, do not worry keep going :)
Hey, I just watched this video after std::array and you contradicted yourself. Maybe because you didn't know it when you created this video but in this one you say there's an overhead due to size() but in std:: array video you pointed out that it's a template and does not add any overhead as it simply returns the value. Just wanted to make sure people watching this know that you actually recommended using std::array over c-style array due to many advantages.
@@andruha1067 The overhead is the whole bounds checking and whatnot.
@@andruha1067 I agree, but as @FFS said, yes, there are many bound checking, and other "CHECKS" which a bit slow down the performance of our code
cherno: "We're gonna wrap this up pretty soon"
me (moving mouse):"no, you're not"
XD
lol this literally just happened to me aswell
same lol
Part of what makes you a great programmer/teacher is that you have a deep technical understanding of how all of this works, and you're not afraid to share that information even though it may seem intimidating.
Agreed: Sometimes it's tough to know what the audience already knows, I guess it's always good to error on the side of over explaining.
That's how u know he's about that LIFE.
"I like to live dangerously" Lmao
@@thecashewtrader3328 I'm pretty sure Austin Powers said this before GTA SA
_"Hey, Pikaju!"_
TH-cam C++ videos are like looking up a word in a dictionary and the definition is full of words you don't understand so you look up those words and the chain continues. AAAAARRRGGHH!!!!!!! *slams head on desk*
Bruuuuh. I know this was 2 years ago but I'm going through the same thing. I'm always checking the comments to see if people understand and surprisingly, they seem to. But maaaan!!!
@@mwenge6355That's normal for everyone that is starting, don't worry.
@@mwenge6355 I understand almost all of his videos, the reason is that I've been programming for almost 10 years now, so my advise is to practice video by video and look up some written docs of the same concept that you didn't understand from the video. good luck
this is actually part 30 of a series.
theres a 106 episode playlist. the people who are getting it have been watching from the begining.
you see a lot of people be confused in the virtual functions video because he introduces new concepts without eplaining them (virtual destructors, -> operator, new keyword, heap vs stack) but he has videos on all 4 of them so when you get to that video, you branch out and watch those 4 videos and then come back and you get everything
You have made me finally UNDERSTAND pointers PROPERLY. I see their potential now. Its just you accessing memory locations and playing around with either those locations or the values in those locations. That is all pointers are !! They are not doing anything weird. Smh. Thanks man. You have no idea how clear this has made things for me. Makes we actually want to learn Machine/Assembly Language
17:56 "however....i like to live dangerously"...XD
Dude, phenomenal video.
Love the technicality (pointer arithmetic (assembly OFFSET), heap alloc/dealloc, little endian, constexpr, c++11 arrays, etc)... great stuff
I'm absolutely loving this series, you should extend this series with a playlist on DSA, Arrays, LinkedList Stacks Queues BST Heaps, and then perhaps different types of algs, sorting and graphing algs
5:16 Actually, less than or equal to is not performed separately, as (less than OR equal to) is the opposite of greater than, and vice versa. However, the code is more readable and more understandable if you write for (int i = 0; i < SIZE; i++) instead of for (int i = 0; i
Correct. In this case the compiler will emit a JL (jump if less) or JLE (jump if less or equal) operation (on an x86 processor) for < or
@Ebola Virus It may depend on how the emitted code is structured. In a very typical for loop you're counting up to some limiting factor so at the bottom of the loop you do the test and jump back to the top if the counting variable is less than the compared value. However, this is very dependent on a) the code that the programmer wrote (obviously) and b) how the compiler, optimizer and code emitter organize the object code. In the x86 world JNL is an alias for JGE (jump if greater or equal). These conditional jump instructions test flags in the flags register to determine whether to jump or not. They can test multiple flags simultaneously, such as the O(verflow) and S(ign) flags in the case of JL/JNL
If you wrote *for (int i = 0; i < 5; i++)* then I'd expect the compiler to emit something like:
for_loop:
.
.
mov rax, [esp-8] ; i
add rax,1
mov [esp-8],rax ; changes no flags
cmp rax, 5 ; sets CF,OF,SF,ZF,PF,AF flags
jl for_loop ; jump if SF != OF
nop
In the case of *i < 5* the Sign Flag will be set but the Overflow Flag won't be and the jump will be taken. In the case of *i == 5* (the terminating condition) both the Sign Flag and Overflow Flag will be reset and the jump won't be taken and the CPU will continue at the NOP in this case.
There's nothing stopping you writing code like this:
loop_top:
mov rax,[esp-8] ; i
inc rax ; adds 1
mov [esp-8],rax
cmp rax,5
jl loop_body
jmp somewhere_else
loop_body:
; do something
jmp loop_top
This is slightly less efficient, but the compiler (or hand-written assembler) might produce that kind of structure depending on size of code blocks, processor mode, etc. (in the "old days"(8/16-bit code), a conditional jump could only move the instruction pointer by -126/+129 so you'd have to reverse the sense of the conditional jump and use an immediate 16-bit jump e.g. if the loop code was longer than the distance allowed in the relative conditional jump.
The only issue in the video was that Yan incorrectly said that writing e.g. *i
but the computer does not understand that. it is why there exists a greater than or equal to operator
@@treyquattro Modern compilers won't emit a JL or JLE instruction, it will convert it into a JE instruction and compare it to 5 in this case to terminate the loop. Which makes sense considering it's just an XOR that has to be 0 as a result. Whereas if you use a JL or god forbid a JLE instruction it's a bitflip + 2s complement of the second value followed by an addition and subsequent interpretation of the result as a negative or positive number. If you compare sizes and whatnot it actually needs a lot more cycles to do so a modern compiler will omit that instruction. Check Godbolt if you doubt me.
@@Finkelfunk it's up to the compiler and optimizer how it organizes code - what tests and jumps it makes. There may well be optimizations to be made in the arrangements of what conditions to check, but etiher way a jump is going to be made either when the final condition is reached, or when an intermediate condition happens, depending on how the compiler has decided to lay out the code. The issue is that whether the compiler decides to emit JE, JL, JLE or something else (you may see aliases such as JC or JNAE for JB e.g.), the instruction timing is going to be identical - it's a test of a flag and a jump or not on result. Different flags get tested by different instructions but all Jcc (jump on condition code) operations (x86_64) have the same timing for the same sized operands. Saying check it on Godbolt is not very helpful because there are tens of different compilers on Godbolt, each with a variety of optimization settings. What gets generated differs from compiler to compiler, and version to version, and depending on the optimization levels chosen.
The original issue was that it was mistakenly asserted that a
So to summarize:
Arrays store values of one type together
The Array Name by itself is a memory address
Arrays can be indexed through both for loops and pointer arithmetic
Arrays can be made dynamically or statically (on the stack or the heap)
9:02 this is some wild shit
11:26 a pretty damn good example of *pointer* :D
🤣🤣🤣
😂😂🤫
You're more than a teacher you're a perfect explainer. I wish if there's more like you or as good as you. I've been watching your series from last night and I'm just stuck on your channel. That's awesome.
you are the best so far in my experience of learning online. In my perspective, you don't share knowledge, but rather EXPERIENCE.
I am gonna now watch all the c++ experiences taught by you.
Thank you soooo much.
6:14 just a small correction for the great video, usually the C/C++ runtime knows the size of the arrays (malloc/realloc... other functions) and of course the operating system as well see VirtualAlloc, HeapAlloc, ... on Windows and even on windows the way it's kept differs between the type of allocators which are used (small/medium/large pool allocation)
Please consider making C# videos..! The way you teach, express things is just amazing. I feel like I don't understand other people's teachings.
The Cherno videos have become my morning routine :D
At 16:13 you say "you have to mark it as STATIC". Why doesn't the CONST meen it is known at compile time (if it is constant), why the STATIC as well?
You are easily the best C++ teacher I have seen, and your videos are perfect in style and content.
@Peterolen Yea. because there is no 'readonly' in C++ like it is in C#. There const means compile time const and
'readonly' means that it can be modified in the constructor.
@@vighnesh153 I think the C++ spec recommends to use constexpr instead of const as const is more used as "readonly" now (or I might be mistaken maybe it was someone else lol)
the const keyword is not necessarily known at compile time. It just means it can't be changed once it's initialized. For instance you can have the following:
int i;
std::cin >> i;
const int x = i;
and it is perfectly valid though the value isn't known at compile time. Therefore the compiler would have no way to know how much memory to set aside if you did int MyArray[x]
Whereas constexpr or const static both must have constant values that are known at compile time.
@@vika3750 Thanks for that, Vik A. 🙂
Think I was just getting const and static confused for some reason.
Yes Cherno, we want more long videos please!!
I just finished the series in less than 1 week, thank you so much for this great information.
2 days ;D
@@9696Punk yall are too powerful to be kept alive
@@9696Punk 8 hours a day???????
These are some of the most useful programming videos on the internet because of your teaching style and structure.
First thing that makes you a cut above the rest, is because you cut straight through the bullshit. ie: A variable type is actually nothing special. ie: an array is actually just a small stack of variables, and is sort of actually nothing special.
Second thing: The memory viewer. Mind blown! For as long as I've been trying to learn these concepts (and bowing before variable types with a cult like religious reverence), I haven't found any instructor that actually does this. Instead every tutorial or course (I've taken) leaves this sort of thick fog between memory and what we're trying to achieve. As if memory is this magical thing we must never look upon or speak the name of, except in anything but convoluted riddles. Even in my Computer Science 104 course in college they taught us the hardware concepts of memory on the whiteboard, but never even attempted to connect it's fundamental truths to the code side of things. Makes me feel like Memory viewing should really be a part of the introduction, instead of being left only until advanced concepts.
I've Learned new things today... Thanks.
Playing with addressable LED's with an arduino, Ive seen some weird things going on when I accidentally misuse an array. I had no idea what was going on, LED's doing strange things. I did work out that arrays still try to work, I assumed it just used the memory as if it was bigger. Got some cool effects from it.
I look forward to the spin offs as you say :)
I started playing with arrays, just to remember how it works and found out that you can change a private atribute of a class (even out side of its scope) using pointers, nice >
can explain it ?
16:14 As the size variable should be known at compile time, you've stated that it should be static const (or constexpr). It can also be declared in a #define statement, and easily remembered, like in
#define ARRAY_SIZE 5
int example[ARRAY_SIZE];
Yes, that's exactly what I'm thinking about. Is it okay to write macros in-line with your code? Or is it better to just put all the macros on top of the soruce code?
oh no bro macros are evil (because they literally just replace text in your code) avoid them at all possible costs, use them only if it's absolutely necessary
Let just say I just wanted to learn pointers here and I watched 30 videos. And I learned 10 different things and now I'm excited I learned something new and I'm sure I'll watch all the videos.
In a video of more than 15 min, I usually overwhelmingly check the remaining time. But with Cherno, time flies.
You bring up some basic yet meaningful concepts that other introductory programming texts/videos don't. like why < is better than
Hey man, you are amazing. YOU ARE THE C++ REFERENCE
Hey The Cherno, every so often i see you doing some fancy keyboard combo magic which resembles VIM operations like selecting chunks of code quickly, moving line up or down, duplicating etc. I'd be pretty interested in learning how you've set that up and knowing more about your input "workflow". If you've already done a video on this please link me :)
Very thoughtful introduction - many thanks.
God Bless you. Put more adds on this baby, you deserve money
15:15 the sizeof(pointer) for Visual C/C++ will allways be equal to sizeof(int), because these should be equal to the size of the registers are used in order to not create bottlenecks in CPU operations => the sizeof(pointer)/sizeof(int) will always be 1 for VCRT
You went quite deep in this one. Thanks.
Me: Struggling to get the element count of a heap allocated array and failing miserably.
The Cherno: It's not really possible in C++*.
Me: Suddenly feeling less incapable.
I like these longer videos where you really go in depth!
15:10 i think the size of an integer pointer is 8 bytes and not 4 bytes !
Cherno sos lo mas grande que hay.
Thanks for this!
By the way, you REALLY talk with your hands!!
Can somebody tell what NDNS is(on 12:30)?
8:40: That is a proper "pro" move. Nice
That's a proper "I invoke UB because I don't care about my code". Nobody sane in the industry would ever deliberately invoke undefined behavior, that assignment might as well make your PC order pizza for you.
Me watching this video hoping to clear all confusion just to be greeted by more confusion... Guess I'm on my own now.
15:55 Okay, that is interesting. That actually worked for me (no errors, compiled and executed fine) XD. Weird...
Love these videos. This is helping me out in my cs131 class at evcc
I watched neatly a third of this series. Insane stuff. I'm gonna start trying to mod Open Roller Coaster Tycoon 2 to actually put my skills to use.
where the hell was this series ? such a golden playlist
for using the value of std::array::size() in for loops, you've got to change the data type to signed integer or either declare the variable for the initial value as an unsigned integer
the "perfect" solution would probably be to use size_t for the type of the iterating variable, because by definition size_t "can store the maximum size of a theoretically possible object of any type (including array)"
also, you can just do a ranged for over the array if it is only the elements that you need
16:14, why do you mark it as static?
9:35 “I’m going to wrap this up pretty soon”
But I do like the lengthier video though
3:23 Hey! It's not a pointer.
An array will be implicitly converted into a pointer to its first element, but it's not a pointer.
Pointers store address, and arrays store their elements, so they're definitely different types. If you get the address of a pointer (`&ptr`), the result is a pointer to the pointer; in the other hand, if you get the address of an array, the result is a pointer to the array.
As what you saw, in the memory, there are five integers instead of a "base address".
Mate you are just great!!!
Especially because you teach everything clearly and quickly 😎
Another reason to allocate on the heap is when you don't know at compile time how big you need your array to be (e.g., an array whose size is determined by user input).
Thanks! By watching this series i improved my programming skills in c++ A LOT. I hope you will keep doing such a videos
for loop and arrays are best friends forever
Another great video, way easier to understand then my university teaches.
Thanks
5:23 I checked the compiler explorer and it is in fact not correct that it will do a less than and equals comparison. Basically, compiler magic and all that optimizes it away, so no matter how you write it, it always uses a "je" instruction. But it is definitely more readable to anybody working with your code.
Yes!! We're finally getting to more interesting topics, WOOOOOOOOOO
3:40 Long live negative indices of Python!
Python has negative indices?
Personal Notes:
- there is no array index check in c++
- Pointer arithmetics is done automatically according to the type the pointer points to ( ex: int arr[5]; *(arr+2) accesses the 2nd element)
- Stack: int arr[5]; heap: int* arr = new int[5]
- Why would i need dynamic allocation? One simple example is to be able to return an array defined inside a function
- Since C++17, std::array has been introduced which does bounds checking and knows its size
- Didn’t get why array size must be declared as static const at 16:15
I'm leaving this here in case anyone still has any questions.
- Using a const variable to specify the size of an array inside a class is not allowed because arrays must have a size that is known at compile-time.
- The size of an array must be a constant expression, meaning it must be able to be evaluated at compile-time, so that the compiler knows how much memory to allocate for the array.
- On the other hand, const variables inside a class can only be initialized with a value that can be evaluated at runtime.
- This is because the value of a const variable inside a class is not known until the object is constructed, which is too late to specify the size of an array.
- In order to use a const variable to specify the size of an array inside a class, you should use a static const variable.
- This is because static const variables are shared by all objects of a class, so their value is known at compile-time.
- Another benefit from doing this is that you use a non-static const int to set the size of the array, each object will have its own copy of the size, which is wasteful and unnecessary.
-By using a static const int instead, the size of the array will be shared among all objects of the class and will have a single storage location in memory
If you have any confusion regarding what static and non-static is please refer to Cherno's video on the topic
Daddy Cherno feeding us more videos
"However, I like to live dangerously" xD xD
11:26 nice pointer
best online c++
5:18 you said a "
Most funny things do happen, if your index variable lies nearby your array in the memory.
Suddenly you start to overwrite the index with some value, which belongs into the array. If that happens in a loop, you will, perhaps, never be able to leave this array-hell.
That happend to my team-leader in a real-time, safety regarding, embedded project.
At 16:30, why is static const used ? Why only const won't work?
If for example I have dynamic array of class instances that all need to call destructor, because class contains a pointer, when I call delete[]array will it call destructor for each one instance or do I need to do it separately before calling delete[]?
15:19
int count = sizeof(example) / sizeof(int) ------This does not give us zero; the result of this is : 2
int count = sizeof(*example) / sizeof(int[5]);-----This gives zero
wow it is 2.
maybe it is because you have a 64 bits application so the size of the pointer is actually 8 bytes.
gave up coding!
how about :
std::vectorarr(5)
std::cout
In that case you're initializing the vector class, and the parameter 5 is its size
so std::array myArray is equal to std::vector myArray(5)
Vectors are made on the heap
great stuff cherno
@7:28 I assume then that ptr is a double pointer in this context?
Is there a video from this channel that explains associative arrays/hashmaps/dictionaries ?
concept is tricky in example code but you made it simple . THANKYOU
Chorando rios vendo o vídeo todo em x0,5 pq ele é o melhor professor que eu encontrei mas fala inglês🤡
There are also std::size() and std::ssize() to retrieve the size (or count of elements) of a raw array (although they work for standard arrays as well), I don't know if these methods were there by the time this video was made but if I'm not wrong they seem to be the safe way to do it now.
Cherno, thanks for your awesome videos! could you please make a tutorial series about game programming patterns.
Bro , all what i can say is thank you
keep up buddy
Way to flip us all off at 11:27.
Dude! you are superfast most of the times i have to stop the video and play it in slowmo
16:14 you added static because it could've been changed at the constructor otherwise?
9:12 is really wild.
another EXCELLENT video
@10:53 does this imply that a language like Java will have this overheads built into the language and there is no way around them?
It's called garbage collector. It takes care of deleting objects for you. There might be way to take care of deleting your objects yourself. Not sure, i'm not java expert, but there is no reason really to do it in Java. If you really need the performance gain from dynamic memory allocation, Java isn't right tool to use, C++ is.
Basically yes.
Yes but depending on what you are doing you can try different tricks. Also not all languages are created equal and some are better at different task.
It helped me a lot for my exam
Hi Cherno,
Correct me if I'm mistaken, but are '
8:15 what exacty are we adding to the ptr (ptr+2) , does it mean move forward two the size of the TYPE int which is 8 bytes ? ... i know what example[2] means, but ptr +2 !!
haha just 5 more seconds and you explained it exactly the way I understood it, I love myself at such moments. thanks cherno
the sad thing is i cant tell if youre joking when you say "i dont wanna make this too complicated" XD
thank you for these free tutorials
thank you very much for this information you teached me
Great explanation
you are really great teacher cherno thank you a lot!
Great video. Still, I think this video would make more sense to be the 7th video on the playlist.
just incredible. thank you
5:22 This will probably not be a performance hit. Almost all common ISAs have a single instruction for "jump if less than or equals" that takes the same number of cycles as "jump if less than". (In hardware, the addition of the "equals" check likely has almost no impact on the critical path, since both the less than and equals checks can be done in parallel and the combination is a simple OR)
Thank you very much!
I am element 0 on this array
I can't lie that was a good one...
Josh Stephenson had to pointer that out.
thisarray[0] = myname;
Josh should have said "first" lol
You could use pointer arithmetic to loop through your 50 individual integers.
Oh my God...
Are raw arrays typically used in gaming where performance is key?
Couldn't you also specify a set of values when you create the array rather than use a for loop to define their values?
For example int myArray[5] = {1, 2, 3, 4, 5};
It would be more efficient to use a for loop if you have a large array, but if there are only a few elements it's quicker to write it this way in one line than to write an entire for loop imo.
So I googled how to find the size of an array because I needed it for a code I was working (note, I'm very much still a beginner when it comes to coding), and while one of the methods was that method you showed of doing arrSize = sizeof(arr) / sizeof(value), another way which was mentioned was this way that I prefer but don't fully understand which uses pointers. The code for this is arrSize = *(&arr + 1) - arr. I didn't use this inside of a function, but my guess is it would still work inside of a function considering that it uses pointers and addresses of. Like I said, I don't fully understand the code, only that it works for finding the size of the array, so if anyone could explain it in detail, I know how pointers work, and I know about addresses of, I just don't understand this specific way of finding the size of an array.