Everything You Thought You Knew About Arrays is Wrong (in C Programming). This is Why.

แชร์
ฝัง
  • เผยแพร่เมื่อ 9 ก.ย. 2024
  • An array is a list with a fixed length and type. An array is a special type of pointer variable. An array decays to a pointer when it’s passed to a function.
    People say these things all the time. But is any of it true?
    The fact of the matter is that in C, arrays don’t really exist. What you call an array is just a memory address and when you “index” into it, you are really just doing pointer arithmetic.
    In this video, I dive down deeply to look at arrays at a low level to show both the way arrays are handled in computer memory and how your array definitions are translated into assembly language. By the end of this video, you may think about C arrays in a very different way!
    If you haven’t already done so, I recommend that you watch my other video on arrays before watching this one:
    • The ONE Thing Most C P...
    MORE LESSONS
    =============
    To watch other videos about “low level programming”, go to the “Down To The Metal” playlist:
    • Down To The Metal
    Also, my series on “Programming C in Visual Studio”:
    • Program C in Visual St...
    Be sure to subscribe to the Code With Huw channel so that you get a notification when I upload more lessons in this series.
    PROGRAMMING BOOKS
    ====================
    If you want to learn programming in more depth (and also support this channel!) you might think of buying one of my books. I have written books on C programming, Using Pointers in C, Recursion and other programming topics. You can buy my books (paperback or Kindle) on Amazon.
    ** The Little Book Of Pointers **
    Amazon (US) amzn.to/2LF2aVb
    Amazon (UK) amzn.to/2FViSvS
    ** The Little Book Of C Programming **
    Amazon (US) amzn.to/2RXwA6a
    Amazon (UK) amzn.to/2JhlwOA
    “CODE WITH HUW” ON TWITTER:
    =================================
    / codewithhuw
    “CODE WITH HUW” ON FACEBOOK:
    =================================
    / codewithhuw
    Good luck! And good programming!

ความคิดเห็น • 150

  • @AntonioDoesMetal
    @AntonioDoesMetal หลายเดือนก่อน +69

    "C isn't some low level Java, it's a high level assembly" is such a great way of putting it, really been enjoying your videos

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +5

      Many thanks!

  • @KurtVanBever
    @KurtVanBever หลายเดือนก่อน +26

    You know what's funny? When you hear it explained like this, you start wondering what the problem was in the first place. Thanks for letting us rediscover the simplicity that somehow got lost.

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +6

      I think it's the simplicity that many people (accustomed to more complicated languages) find the hardest to thing to understand.
      Many thanks for the comment.
      Huw

    • @ronald3836
      @ronald3836 27 วันที่ผ่านมา +2

      The problem in the first place is the misconception that, in C, arrays are pointers.
      Unfortunately, Huw decided to perpetuate this misconception (but using the term "address" instead of pointer).
      An array in C is an object that represents a fixed number of consecutive objects of a certain type.
      For example, int a[10] declares a to be an array object of 10 ints.
      This means that "sizeof a" will evaluate to 10 * sizeof int = 40 (assuming ints are 32 bit).
      However, when you use a in an expression, the name "a" is automatically converted to a pointer to the first element of the array.
      But if you take the "address" of a, i.e. &a, you end up with a pointer to the array itself, i.e. a pointer to an object of the array type.
      In other words:
      #include
      int y[] = { 0,1,2,3,4,5 };
      int main()
      {
      printf("%d
      ", sizeof y);
      printf("%d
      ", (char *)(y+1) - (char *)y);
      printf("%d
      ", (char *)(&y+1) - (char *)&y);
      return 0;
      }
      If you run this, you get:
      24
      4
      24
      You can´t explain this with just "arrays are pointers" or (even worse, because discarding the type info) "arrays are addresses".

    • @omegawii
      @omegawii 22 วันที่ผ่านมา

      ​​@@ronald3836bro I'm pretty sure that C doesn't have objects... that's CPP.

    • @ronald3836
      @ronald3836 22 วันที่ผ่านมา

      @@omegawii Bro, I am pretty sure that the C standard knows better than you. You can look it up for yourself.
      C standard, 6.2.5:
      - An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type. The element type shall be complete whenever the array type is specified. Array types are characterized by their element type and by the number
      of elements in the array. An array type is said to be derived from its element type, and if its element type is T, the array type is sometimes called “array of T”. The construction of an array type from an element type is called “array type derivation”.
      C standard, 6.3.2.1:
      Except when it is the operand of the sizeof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type “array of type” is converted to an expression with type “pointer to type” that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

    • @salvatoreshiggerino6810
      @salvatoreshiggerino6810 21 วันที่ผ่านมา

      @@omegawii All the languages have objects, but only some languages are oriented around them. Come to think of it OOP is a pretty misleading name for itself.

  • @andrewgr144
    @andrewgr144 หลายเดือนก่อน +15

    This video seems like a reasonable explanation of how arrays work in 'C', but this information cannot possibly be new or unexpected to any competent C programmer. If we imagine learning C as a 3 quarters college class, C101, C102, and C103, anyone earning a passing grade in C101 would understand how arrays work and not be confused by them; they are, after all, incredibly simple. It might have been better to title the video something like, "C Arrays for Beginners", or "How Arrays work in C".

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +9

      If you look at the comment thread to my last video, you'll find that there is in fact a great deal of confusion. I was first alerted to this when reading some quite well-known C books which gave incorrect information on this. th-cam.com/video/H18yIPSsgLg/w-d-xo.htmlsi=gvSHNxuca_FhAp_7

    • @andrewgr144
      @andrewgr144 หลายเดือนก่อน +1

      @@LearnWithHuw First, thank you for taking the time to respond. Second, I have confirmed your assertion that this is a cause of confusion by seeing the volume of questions that turn up in my search results when I look for variations of "in C language is an array a pointer." I mistakenly assumed that everyone had iterated through an array using pointer arithmetic at some point, in which case the syntax you use makes it clear what's going on. Third, I watched the video you pointed me to, and I don't agree with that last part of your analysis (or better, the last part of your analysis as I understand it); specifically, your discussion of the quote that you display from K&R 1st edition vs. the quote from the 2nd edition. The first edition discusses what a REFERENCE to an array is; the second explains what the VALUE of an array is. A reference is, literally by definition, just another name for an existing object. It must be assigned when the reference variable is declared and cannot be assigned to null. It isn't a variable, and can't be set to a new value. I believe that references are implemented under the covers as immutable pointers (at least conceptually), but I wouldn't want to bet a kidney on it. But in any event, all the quote from the 1st edition is saying is that if you declare a new variable using the & and assign it to an array, that variable now stores the address of array[0]. The statement doesn't actually say or imply anything about what the value of an array is, or what data type an array is. I think the statement is straightforward and true, but I also think it would have been better to have both quotes in the same edition, since they describe quite different things.

    • @simpletongeek
      @simpletongeek 29 วันที่ผ่านมา +2

      In my experience, a full 80% of graduating seniors (BA CS) mixed up Reference and Value! This, despite the compiler giving clear warnings! Teachers and TAs don't care then, and I don't believe they care now.
      Even fewer people realize that they can reference values in an array using an index variable, instead of actual pointer.

    • @TheWallReports
      @TheWallReports 28 วันที่ผ่านมา

      @@LearnWithHuw A minute and a half into the video I am now a new subscriber. As someone who's 1st programming language was BASIC, yes the original BASIC w/line numbers, then ForTran, COBAL, Pascal, FORTH, 6502 machine language & Assembly language this is most accurate description of C arrays. I took the plunge into after acquired the above under my belt. I've always cringed when C programmers would say C is a low-level language when in fact it's more of mid-level language.

    • @LearnWithHuw
      @LearnWithHuw  28 วันที่ผ่านมา +2

      @@TheWallReports Many thanks. Well, yes, I started with BASIC too (GW-BASIC). Awful. But an experience that every programmer should go through in order to appreciate other languages! 🙂

  • @4X6GP
    @4X6GP หลายเดือนก่อน +9

    Ignore the pests. Everything you said is true, and anyone who didn't know these things was helped. Those who knew them already were not injured.

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +4

      Ha! Thank you. That's made my day!

    • @johnkuehler2608
      @johnkuehler2608 หลายเดือนก่อน +3

      One can never the review the fundamentals enough. There is always something to learn or reinforce in a good presentation on subject. Holds true in Math , Physics and Programming. It maybe more relevant today as students are often studying the concepts of CS in languages like Java or Python and are not being drilled in the C language anymore. Valuable that this reference material is out there for those who seek it out.

    • @ronald3836
      @ronald3836 27 วันที่ผ่านมา

      In your view, does C have array types different from pointer types?
      If yes, then arrays are not pointers!
      Of course the answer is yes. Array types are not pointer types.
      (Huw's initial video on this set out to show that arrays are not pointers, but addresses. Of course a pointer is really just an address (with type info).)

  • @AlberTesla1024
    @AlberTesla1024 27 วันที่ผ่านมา +4

    I studied and knew this since I studied assembly, but the way you represent is so captivating. I still gave the look into it.

    • @LearnWithHuw
      @LearnWithHuw  27 วันที่ผ่านมา +2

      That's very kind of you. Many thanks!

  • @compphysgeek
    @compphysgeek หลายเดือนก่อน +6

    that "Danger"ous part reminded me of the days of C64 programming, where you would just poke data at memory addresses

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +4

      These days, that sounds like the crazy world of microcontrollers! 🙂

    • @higgins007
      @higgins007 29 วันที่ผ่านมา +2

      Still what we're doing really, just with a seemingly infinite number of layers, abstractions, api's and obfuscations between us and the actual memory we need to read/write to. Man I hate "modern" programming!

    • @ronald3836
      @ronald3836 27 วันที่ผ่านมา +3

      When I still lacked a real grasp of how my C64 worked, I was playing around with "bouncing ball" programs in BASIC. Somehow my program tended to get corrupted all by itself, and I thought my C64 might be broken. But instead of returning my C64 to the shop I managed to figure out what was happening: the ball ended up offscreen due to an off-by-one error. The screen memory ran from 1024 to 2023, and the BASIC program started from memory location 2049. So poking the ball slightly south of the screen meant overwriting and thus corrupting the program.
      Suddenly I understood how computers worked 🙂

  • @redemptusrenatus5336
    @redemptusrenatus5336 หลายเดือนก่อน +3

    I did look into this because I remember someone mentioning sizeof() and trying to make it out like arrays in C were objects of some sort, etc. And I remembered sizeof() being evaluated at compile time where it replaces the statement 'sizeof(y)' with a simple constant and that number is what is used rather than any sort of special metadata being referenced during runtime. Someone mentioned while I was looking this up that it remains true for regular C arrays but in C99 it changes for Variable Length Arrays (VLAs) as they are calculated during runtime instead which is of course, a different case entirely.

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +3

      I'll note that down as a topic for a future video! 🙂 Thanks for the comment. Huw

    • @arrabalamargo
      @arrabalamargo หลายเดือนก่อน +3

      @@LearnWithHuw In those ancient times as well as today, integers are not of the same length across the platforms. sizeof() helped and still helps navigating these vagaries.

    • @johnkuehler2608
      @johnkuehler2608 หลายเดือนก่อน +4

      Covering sizeof was good. I learn C back in 80s and moved on before C99 was widely adopted, and the compile time is way I learned it. It is good to review these things we take for granted as the appear the same, but not quite in later iterations'. Good video of the foundations of C .

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน

      @@johnkuehler2608 Many thanks.

    • @ronald3836
      @ronald3836 27 วันที่ผ่านมา +1

      Arrays in C certainly are objects of some sort (objects of the array type to be precise). If you don't believe it, look it up in the C standard.
      Of couse sizeof is evaluated at compile time since C is statically typed. That does not mean that array types are not a thing in C, as Huw is somehow trying to argue (the logic escapes me). They certainly are. Otherwise, you could not define 2-dimensional arrays (which are really arrays of arrays -- can't do that with pointers).

  • @NikolaNevenov86
    @NikolaNevenov86 19 วันที่ผ่านมา

    I think my comment on this from the previous video was correct that I view an array as a pointer...which is just an address but I have to admit, I never thought that we could outright go to an address and write to it with the syntax you provided as if an array. Knowing that the array element syntax is just a compiler level syntax sugar, it makes sense thought. That being said you casted the address to an `int`, I suppose you could had casted it to a `short` or `char`, except that would write to a different part of that memory?
    The `sizeof()` explanation was helpful, it cleared in my mind why an array created with `malloc()`(given the explanation that an array is just a pointer/address) will have a `sizeof()` return the size of the pointer, while a stack created array will have it's `sizeof()` return the size of the array. It's just compiler knowing in advance the size of the stack allocated one.

  • @oglothenerd
    @oglothenerd หลายเดือนก่อน +3

    I am proud of myself for knowing this already. 😊

  • @dantenotavailable
    @dantenotavailable 29 วันที่ผ่านมา +1

    I was totally expecting you to say that 0x41a020 is an array of three 8 bit integers (four if you count the insignificant top byte) from a certain point of view.
    Good video!

  • @johnkuehler2608
    @johnkuehler2608 หลายเดือนก่อน +2

    Like these videos that go back to the fundamentals.

  • @markuszeller_official
    @markuszeller_official 22 วันที่ผ่านมา

    This is so simple now and entertaining after reading your books and doing some practice! 💙

    • @LearnWithHuw
      @LearnWithHuw  22 วันที่ผ่านมา +1

      That's very kind. Many thanks.
      Huw

  • @tordjarv3802
    @tordjarv3802 26 วันที่ผ่านมา +1

    Arrays in C are not addresses. As I pointed out on your previous video on the topic the C standard (which defines the programming language C, unlike the msvc which is just one of many implementations of it) an array is:
    An array type describes a contiguously allocated nonempty set of objects with a
    particular member object type, called the element type.36) Array types are
    characterized by their element type and by the number of elements in the array. An
    array type is said to be derived from its element type, and if its element type is T , the
    array type is sometimes called ‘‘array of T ’’. The construction of an array type from
    an element type is called ‘‘array type derivation’’.
    I also showed that in some cases, some C compilers (such as gcc and clang) will put the array in a single vector register such as xmm0, in which case they won't have an address at all.
    With your logic, everything that resides in memory is an address. Would you say a struct is an address, would you say that an int is an address?
    Saying that an array is an address is analogous to saying that a house is its street address. Just imagine if someone dugg that house up and moved it to somewhere else, would the house have the same street address. No, but the house would still be the same.
    To be perfectly clear, I do not say that an array is a pointer (you seemed to think that last time).

    • @Forrester-i4d
      @Forrester-i4d 25 วันที่ผ่านมา +1

      I'm aware of the C standard. It's very good for language lawyers and people who like to implement standards. But the section you quote is perfectly consistent with the statement 'an array is an address' - the two are not mutually exclusive.
      Now, I can treat what is at the address in any way I want. Nothing stops me - I can cast to int*, char* or whatever. I can index outside the bounds of the array as I like. So does the array address or memory at the address change when I cast it? No, of course not. The thing that doesn't change is the address. That is the primary and enduring aspect of an array. I can change the stride and index at will - and apart from the risk of a machine exception - it works.
      The section of the standard that you quote tries - and generally suceeds - in attempting to make the concept of an array precise so that a compiler implementer (e.g. me) has a good idea of what we're doing. It does not negate the concept of an array being an address - at least to my rather empirical mindset.
      Concerning your point on 'xmm0': this is really a point concerning optimization. A good optimizer - and they are very good these days - can totally re-write your code so that it is unrecognisable and completely eliminate variables and even arrays. Huw is showing unoptimized code that can be understood using the debugger - not highly optimized production code.

    • @LearnWithHuw
      @LearnWithHuw  25 วันที่ผ่านมา +1

      @@Forrester-i4d and @tordjarv3802 Many thanks for that interesting discussion. It's given me some ideas for more videos on the nitty-gritty details both of casting and the effects of optimization!
      Best wishes
      Huw

    • @tordjarv3802
      @tordjarv3802 25 วันที่ผ่านมา +2

      @@Forrester-i4d even if we ignore the optimization situation, I still think that it is wrong to say that an array is an address. It has an address, but it is not an address. That the compiler uses the address to refer to the array is irrelevant, it is no different from referring to a particular house by using its street address, but the house is not the address. The address is a way to tell the CPU where the array is, not the array it self. In fact in the unoptimized case, every kind of data has an address, but would you say that a single precision floating point number is an address? For me it feels like the worlds "is" and "has" are confused in the video and that the 'thing' is confused with the reference to the thing. It is sort of like saying that the animal "cat" is literally the same thing as the letters 'c', 'a', and 't'. One is a living breathing organism and the other is a string of symbols. Anyway, I feel like I don't really seem to get the point across so I will give it a rest.

    • @qy9MC
      @qy9MC 13 วันที่ผ่านมา

      ​@@tordjarv3802 I enjoyed reading this, thanks for your input. You did get your point across. Roughly "Everything usually has an adress but that doesn't mean it is just an adress". But in real world use when you pass an array to a function it doesn't make a copy of it, it is not passed by value, it passes as pointer, so practically it is treated as a pointer that happens to point to an array. This fact is further pushed by the fact that you can't return an array, at best you'll return the pointer to an array. So especially for beginners (target audience of this video) it is rather helpful to say they're pointers because they'll have to treat it as such almost always anyway.

  • @KennethSorling
    @KennethSorling หลายเดือนก่อน +2

    Thanks for this video.
    It's fun (and a little nostalgic) to see that your coding style is pretty much how I learned C way back when.
    Is it not permissible to combine variavble definition and initialization? Or are you still adhering to the old Pascal rule that
    variable definitions must go in the top of the procedure, before any use of them?
    I mean, you could have initialized the arraysize variable at the point of definition, but chose not to.

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +1

      I am probably rather Wirthian in my programming style! 🙂

  • @MichaelJamesActually
    @MichaelJamesActually 23 วันที่ผ่านมา

    thank you for this! a few questions from someone who has never read k&r
    1. how does C know to use the same memory address every time you declare the y array?
    2. I thought that this was common across languages, that when you got down to where data was stored. it was either a linked set of addresses or a sequential defined area.

    • @LearnWithHuw
      @LearnWithHuw  23 วันที่ผ่านมา +1

      1. I explain this in the video somewhere. In Visual Studio, there is a linker option that causes the same addresses to be used. This is not the default and must be explicitly set.
      2. In an array (in C), the elements are stored at sequential addresses. This is likely to be true in most other languages too - though it may not be obvious since higher level languages may have all kinds of constructs to hide the storage details from the programmer - that is, by interfacing between the code and the data using high-level objects, methods, properties etc. In C, an array is not a high-level construct. It's just an address (followed by sequential addresses) at which one or more data items can be stored.

    • @MichaelJamesActually
      @MichaelJamesActually 23 วันที่ผ่านมา +1

      @@LearnWithHuw thanks!

  • @corwin-7365
    @corwin-7365 15 วันที่ผ่านมา

    Answers to Huw's rhetorical questions:
    o _An array is a list with a fixed length and type_ - True.
    o _An array is a special type of pointer variable_ - False.
    o _An array decays to a pointer when it’s passed to a function_ - True (and any other situation where an array is used where an RValue is required).
    o _The fact of the matter is that in C, arrays don’t really exist_ - False.
    Array *_types_* exist. You can see that by doing a typedef. Eg:
    *typedef int A5[5]; // Type 'A5' is the type 'an array of 5 int's'.*
    Array *_variables_* exist and can be defined: Eg:
    *A5 a; // 'a' is a variable of type 'A5'.*
    You can see that 'a' is a variable (LValue) because you can apply the '&' operator (which can only be applied to LValues) to it. Eg:
    *A5** *p; // 'p' is a pointer to a variable of type 'A5'.*
    *p = &a; // Apply the '&' operator to the array variable (LValue) 'a'.*
    Note that 'p' points to a *whole array,* not an element of it, and so the results of pointer arithmetic on 'p' are undefined.

  • @kwameokrah7662
    @kwameokrah7662 วันที่ผ่านมา

    Thanks for sharing such high caliber knowledge! I struggled to understand the C language coming from the R/Python data science world. After randomly deciding to learn some assembly language (which was a lot easier than I thought it would be) most high-level programming language concepts are some how easier to understand/appreciate...especially C. Even though I don't use C for work it is my favorite programming language now.

    • @LearnWithHuw
      @LearnWithHuw  วันที่ผ่านมา

      Thank you. The power of C can be addictive. But it can be a challenge to learn if you are moving from some more "programmer-friendly" language.
      Best wishes
      Huw

  • @KanjiCoder_RTFM
    @KanjiCoder_RTFM 29 วันที่ผ่านมา +2

    I always pass arrays into functions as : &( array_name[ 0 ] ) because I think the difference between an array and pointer is just extra complexity there to screw me up when I decide to use sizeof and dont account for pointer decay .

  • @xlerb2286
    @xlerb2286 24 วันที่ผ่านมา

    With C if you ever wonder if a feature is some high level bit of functionality or just syntactic sugar around grungy pointer manipulation the later is likely correct. So dig into it like in this video and see how it works. It's been ages since I've coded in C/C++ but I still remember having to play some pointer tricks now and then.

    • @LearnWithHuw
      @LearnWithHuw  24 วันที่ผ่านมา

      Ha! Yes. C is certainly not a language for anyone who's afraid of pointers!
      Thanks for the comment.
      Huw

  • @WolfgangFeist
    @WolfgangFeist 27 วันที่ผ่านมา

    Thanks a lot --- as often, understanding what's really going on makes things much easier.

    • @LearnWithHuw
      @LearnWithHuw  27 วันที่ผ่านมา

      Many thanks. I'm glad it helped.

  • @ada.batungbakal
    @ada.batungbakal 22 วันที่ผ่านมา

    Woohoo, received my two little books today: Pointers and C programming. Excuse me, I’ll start devouring these books 📚

    • @LearnWithHuw
      @LearnWithHuw  22 วันที่ผ่านมา

      Take them slowly. One bite at a time! 😁 I hope you have fun!

  • @MrTheoJ
    @MrTheoJ 27 วันที่ผ่านมา

    Everytime somebody says, "we store a number in 4 Byte" I always hear in my head: 4 bit, which seems a reasonable small amount. Then I realize it's 4 Byte which always seems to me to be a massive amount of space to store an itty-bitty number
    Love the video

    • @LearnWithHuw
      @LearnWithHuw  27 วันที่ผ่านมา +2

      I'm old enough to remember when ever single K counted. I think the first Turbo Pascal compiler and editor I used in the early 80s was a 35K executable, leaving lots of free space for my programs on a single 360K floppy disk. It sounds impossible now, but that's how it was back then.
      Thanks for the comment.
      Huw

    • @LearnWithHuw
      @LearnWithHuw  27 วันที่ผ่านมา +1

      I just checked. Turbo Pascal 3 was a .com file which (including the compiler and editor) came to a massive 39K. Every single bit must have been put to good use in that!

  • @steveo4749
    @steveo4749 23 วันที่ผ่านมา

    Thank you for the clear discussion of C array implementation. C is so powerful, but is unforgiving on letting you do some very stupid things. I subscribed and look forward to more of your videos.

    • @LearnWithHuw
      @LearnWithHuw  23 วันที่ผ่านมา +1

      Yes. There were a few comments on one of my videos in which people asked how C "protects" you from certain catastrophic errors. The answer is: it doesn't. You are on your own!
      Thanks for your comment. Much appreciated.
      Huw

  • @omegawii
    @omegawii 22 วันที่ผ่านมา +1

    I think people are confusing C with CPP.

  • @michaelkotthaus7120
    @michaelkotthaus7120 27 วันที่ผ่านมา +2

    Thank you for this interesing episode.
    "An C array is just an address."
    I cannot completely affirm this statement. As you later explain, the compiler "knows" some more properies of the C array at compile time. Beyond its start address the compiler particularly knows
    - the data type which the array holds
    - the amount of allocated memory for that array
    (and indirectly by both information the number of elements which it can store without overwriting foreign memory).
    If a C array was only an address, I could ask the compiler to set the third element of any array to 17. But as you showed in your example, this did not work. The compiler needs to calculate the offset relative to the start address by multiplying the index with the size of a single element. Also, it knows how many bytes must be affected by the assignment (this could be 4 bytes for an int or 8 bytes for a double on a certain platform, or 20 bytes for an array of a struct.) This information is not present if you have a raw address.
    In your example you gave the compiler this extra information by reinterpreting this addess as an pointer to a certain type. By using this cast operator, it becomes your responsibility that it is either the same type you allocated the memory for or that at least the alignment rules match, compare the (strict) aliasing rules. This type punning may work on a certain CPU, but may fail on another.
    So, the concept of a C array is more than its (start) address.

    • @ronald3836
      @ronald3836 27 วันที่ผ่านมา +1

      The funny thing that the intiial video tries to address the common misconception that arrays in C are just pointers. But he effectively ends up arguing that arrays are pointers ( = addresses). So he falls for the misconception.

    • @jeffspaulding9834
      @jeffspaulding9834 25 วันที่ผ่านมา

      @@ronald3836 He's rather clear on that, actually. Pointers aren't addresses. Pointers contain addresses. The address is the value.

    • @ronald3836
      @ronald3836 25 วันที่ผ่านมา

      @@jeffspaulding9834 No, pointers are addresses (plus type info). A pointer variable contains a pointer. The malloc() function returns a pointer.
      Of course the term "pointer" is often used sloppily (even in K&R, as I noticed, but K&R also states that malloc() returns a pointer).
      If "ptr" is a pointer variable, then "ptr" when used in an expression evaluates to the value of the variable, i.e. to the pointer it contains.
      Anyway, an array is neither a pointer variable nor a pointer/address.

    • @ronald3836
      @ronald3836 25 วันที่ผ่านมา +1

      @@jeffspaulding9834 I believe the misconception that indeed does exist is that arrays "are" pointers (i.e. pointer values/addresses).
      Huw seems to have become aware of the existence of a misconception but misunderstood this by confusing pointers with pointer variables. So he made a video to explain that an array is not a pointer variable.
      But in that video he ends up arguing that an array is a pointer (i.e. address/pointer value). In other words, he fell for the very misconception he wanted to address (but misunderstood).
      But even if the above reconstruction of mine is wrong: arrays in C are not addresses/pointer values. C has array types, which are definitely different from pointer types. So an array value is not a pointer value. However, an expression in C that "seems" to contain an array value in most cases evaluates to a pointer to the first element of the array (rather than to the value of the array, i.e. its contents).

  • @linuxier1986
    @linuxier1986 15 วันที่ผ่านมา

    Very informative

  • @ada.batungbakal
    @ada.batungbakal 13 วันที่ผ่านมา

    On the _Little Book of Pointers_ page 44 (ReturnStrings), I added the format string %s an argument to both printf calls; I got warning: format string is not a string literal. No biggie, just wanted you to know. I do enjoy your book a lot - lots of eureka moments on my side. Thank you

    • @LearnWithHuw
      @LearnWithHuw  11 วันที่ผ่านมา

      Thanks. I'm not exactly sure what code you've written here. Can you paste it as a comment? Thanks.

    • @LearnWithHuw
      @LearnWithHuw  11 วันที่ผ่านมา

      I just tried this and it doesn't cause any problem. Did you make any other changes?
      printf("%s", string_function("Fred"));

    • @ada.batungbakal
      @ada.batungbakal 11 วันที่ผ่านมา

      @@LearnWithHuw no other changes except for the formatting string

    • @ada.batungbakal
      @ada.batungbakal 11 วันที่ผ่านมา

      @@LearnWithHuw
      printf(“%s”,string_function(“Fred”));
      printf(“%s”,string_function(“Gussie Fink-Nottle”));

    • @ada.batungbakal
      @ada.batungbakal 11 วันที่ผ่านมา

      Apologies sir, I replaced #include with #include because I get fatal error: ‘malloc.h’ file not found

  • @christosbinos8467
    @christosbinos8467 28 วันที่ผ่านมา

    What an excellent video. I think all the confusion around such fundamental concepts relates to the newer form of learning programming which emphasizes seemingly productive output at the cost of understanding.
    People learning through quick tutorials, bootcamps etc.

    • @LearnWithHuw
      @LearnWithHuw  28 วันที่ผ่านมา

      Many thanks. Yes, I get the impression that many people learn lots about concepts and paradigms at the expense of the practicalities of hands-on programming. I'm glad you liked the video! 🙂

    • @sohigh7433
      @sohigh7433 25 วันที่ผ่านมา

      I finished a 6 month JavaScript bootcamp and already knew most of that stuff (except the bit about passing arrays to functions but I guess I just never encountered that in a high level language). I have friends with masters in SWE that would lose their marbles if they watched this video. It's not the bootcamps or tutorials. It's the lack of interest about how things work.

  • @quadratwurzel4124
    @quadratwurzel4124 17 วันที่ผ่านมา

    Turns out everything I thought I knew about arrays is right.

  • @redemptusrenatus5336
    @redemptusrenatus5336 หลายเดือนก่อน

    I've been looking forward to this, thanks Huw! 👍

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +1

      More to come soon. 🙂

  • @sleepsmoothsounds
    @sleepsmoothsounds 24 วันที่ผ่านมา

    Amazing ❤😊 thanks for the great content

  • @shaunskosana2202
    @shaunskosana2202 หลายเดือนก่อน

    This memory address is good for mapping this on screen. They way explain didn't know can find like that.

  • @gabriellevesque2185
    @gabriellevesque2185 หลายเดือนก่อน +1

    The DANGER should've started when the "y" variable name wasn't used to assign values and used static addresses directly! Not only when the "y" declaration was removed 😅

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน

      To be fair, the Danger probably should have flashed throughout the video! 😁

  • @borchen0
    @borchen0 29 วันที่ผ่านมา +1

    The memory-view in hex is 'strange' for me, being used to programming the big-endian Motorola 68000 ; )

    • @Lord-Sméagol
      @Lord-Sméagol 28 วันที่ผ่านมา +1

      I started coding in Z80 (little-endian) on my Nascom 1, then Nascom 2,
      followed by a tiny bit of 6502 (also little-endian) on a BBC Computer.
      Then I did some 68010 on my Gauntlet PCB and 68000 on my Amiga 500 upto Amiga 4000 with FPU.
      My first x86 (little-endian) coding was 32-bit [I didn't even bother with 16-bit], as my first PC was a 486 [just to play Doom].
      I still code some x86-64, MMX, SSE, SSE2, AVX, AVX2 if I really need performance, but Microsoft Visual Studio makes it quite easy to include CPU Intrinsics to gain decent performance.
      [I could make use of AVX512, but that would need an expensive upgrade].
      I recently did a little more 6502 and some 6809 (big-endian) [disassembling Williams Defender].
      All that makes it quite easy for me to 'switch-endian' with hex view :)
      I did so much Z80 that I can code it in hex without looking up the instructions! :)

  • @ShuAbLe
    @ShuAbLe หลายเดือนก่อน

    Thanks for the great explanation! Are these adresses of physical or virtual memory? I was under the impression that a process running above the OS can't access physical memory directly without special permissions, working only with the virtual memory space provided by the OS, preventing the process of "stepping" on another process memory space.

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +1

      In Windows (and many other OSes), the addresses are in virtual memory. But that's not always the case with, for example, microcontrollers (for which C is widely used) where you may be addressing physical memory.
      Thanks for the comment.
      Best wishes
      Huw

    • @ronald3836
      @ronald3836 27 วันที่ผ่านมา

      As far as the process is concerned, it's just memory. The point of virtual memory is that the application programmer does not have to worry about it (or about other programs that may be running on the same computer).

  • @blenderpanzi
    @blenderpanzi 26 วันที่ผ่านมา

    Me, looking at that thumbnail: What are car rays? Do cars give of radiation now!? o_O

  • @gaborm4767
    @gaborm4767 หลายเดือนก่อน +1

    What is it that makes you claim it’s not what I thought? What do you think I think?

    • @LearnWithHuw
      @LearnWithHuw  หลายเดือนก่อน +5

      I am not at liberty to reveal my mind-reading powers! 🙂

  • @corwin-7365
    @corwin-7365 19 วันที่ผ่านมา

    This video was a good try... but in the end it is quite disappointing. :-( I won't go so far as to say that Huw is wrong... exactly... but he definitely adds more smoke than clarity to a subject that already confuses many people. The 'memory address' thing (while an interesting side diversion on how compilers implement non-register variables) is a red herring. The thing that makes C arrays & pointers different from other more traditional languages of the era can be described completely using the abstract concepts of pointers & arrays without ever looking at underlying compiler implementation and physical memory addresses.

  • @Brad_Script
    @Brad_Script 25 วันที่ผ่านมา

    how do you make the array always have the same memory address in other compilers ?

    • @LearnWithHuw
      @LearnWithHuw  24 วันที่ผ่านมา

      I haven't tried that. If the option is available it should be somewhere in the linker (or maybe in the build/compile) options either for the entire workspace or for the current project.

  • @ijabbott63
    @ijabbott63 28 วันที่ผ่านมา +1

    That's one way to look at it, although I prefer to use the C standard definition of an array object.

    • @ronald3836
      @ronald3836 27 วันที่ผ่านมา

      You are of course right (and this video is nonsense).

  • @spiderjuice9874
    @spiderjuice9874 25 วันที่ผ่านมา

    So, let me check by asking a stupid question: if we reserve a block of memory with malloc(), then we can do what you did (from 5:57) with no fear of blowing up our program... to have complete correspondence, we just read out the numerical value of what malloc() returned to us and cast it to int * and it should run the same, right? (Too lazy to set it up right now!)

    • @LearnWithHuw
      @LearnWithHuw  25 วันที่ผ่านมา

      In principle that should work. In practice, I can't think of any reason why you would want to do it. Also, bear in mind that the actual address (when using malloc()) won't be available at compile-time so I don't think you'll be able to do what I've done in this video. Anyway, this is an interesting problem for a rainy day. Naturally, for real-world programs, the array syntax deals with most of the messy stuff for you.
      Best wishes
      Huw

    • @spiderjuice9874
      @spiderjuice9874 24 วันที่ผ่านมา

      @@LearnWithHuw Oh, I realize that there's likely no point in doing what I suggested, I was just wondering if it would work after watching your video. I mean, normally, you wouldn't do what you did either - you were making a point in an educational sense, but what you did does not improve readability either :)
      Not being critical of you - I found your subject fascinating!

    • @LearnWithHuw
      @LearnWithHuw  24 วันที่ผ่านมา

      @@spiderjuice9874 Many thanks.

    • @corwin-7365
      @corwin-7365 15 วันที่ผ่านมา

      @spiderjuice9874, Most of C is pretty abstracted from the machine underneath (and so you can compile most programs on many different systems) including Pointers when they are used normally. However, the language does allow for *_some_* operations that depend on compiler and/or machine internals... although the language specification *describes when this is the case.*
      One of these machine/compiler dependent areas is conversion between pointer types, or between pointers and integers. The result is *mostly undetermined* but certain rules do apply (quoting from K&R here, so newer C's may be a bit different):
      - A pointer may be converted to any integral type *_large enough_* to hold it (the mapping is machine dependent but designed to be unsurprising to those whose understand the machine).
      - An object of integral type may be explicitly converted to a pointer. The mapping always carries an integer converted from a pointer back to the same pointer, but is otherwise machine dependent.
      Thus (assuming 'unsigned long' is large enough to hold a pointer) we can do:
      int *p;
      unsigned long ul;
      p = (int *)malloc(3*sizeof(int)); // Allocate a three element array of 'int' on the heap.
      ul = (unsigned long)p; // Machine dependent conversion of a pointer to an integer.
      printf("%lu
      ",ul);
      ((int *)ul)[0] = 111; // Reverse conversing back to a pointer.
      ((int *)ul)[1] = 222; // Reverse conversing back to a pointer.
      ((int *)ul)[2] = 333; // Reverse conversing back to a pointer.
      Note also that:
      - A pointer to one type may be converted to a pointer to another type, however the resulting pointer may cause a memory exception upon use if it does not point to an object suitably aligned in memory.
      Note: The 'malloc' function is *specifically designed* to return a pointer that is correctly aligned for all types that need alignment on the underlying machine.
      However:
      char c;
      int i;
      i = *(int *)&c; // May cause a memory trap error if 'int' and 'char' align differently on the specific machine!
      Also:
      - It is guaranteed that a pointer to an object to a given size can be converted to a pointer to an object of a smaller size and back again without change.
      Ie, the following is guaranteed to work:
      int i;
      int *pi;
      pi = (int *)(char *)&i; // Gets a pointer to 'i'.
      but the following *might* not:
      char c;
      char pc;
      pc = (char *)(int *)&c; // Might get a pointer to 'c'... but also MIGHT NOT!
      This is because a fixed memory size can fit more copies smaller sized data in it than of larger sized data, so the address range of smaller objects is conceptually larger. This was more of an issue in older mainframe computers that had large memory word sizes and small address spaces than current computer designs. But it IS machine dependent.
      :-)

  • @everythingcouldbesimplify818
    @everythingcouldbesimplify818 24 วันที่ผ่านมา

    what about C# it has oficial unsafe way to handle pointers, but everybody is afraid of it because they don't know C to begin with

    • @LearnWithHuw
      @LearnWithHuw  24 วันที่ผ่านมา +1

      I've been thinking about covering unsafe programming in C#. Thanks for the reminder! 🙂

  • @ronald3836
    @ronald3836 27 วันที่ผ่านมา

    Just to be clear: can you confirm that you disagree with nearly everything that is written in the top-rated StackOverflow answer to the question "In C, are arrays pointers or used as pointers?" ?

  • @j-p-d-e-v
    @j-p-d-e-v หลายเดือนก่อน

    Hope you can tackle Rust in the future.

  • @ronald3836
    @ronald3836 27 วันที่ผ่านมา +1

    "arrays in C don't really exist" is just as "true" (and nonsensical) as "floats in C don't really exist -- they are just a couple of bytes".

    • @ronald3836
      @ronald3836 27 วันที่ผ่านมา +1

      Perhaps the best way to get to the crux of the matter: in C, array types exist, and they are not pointer types.

  • @FraggleH
    @FraggleH หลายเดือนก่อน +3

    So you're really doubling down on this nonsense, huh?
    Your 'debunking' of the sizeof point is the most hilarously ridiculous hand-waving I've seen in a good while. First, it doesn't make a blind bit of difference to the point whether sizeof is an operator or a function. What matters is its specified behaviour. The fact that you spend so long on this irrelevance (as if anyone was relying on it being a function for their argument), as well as the arrogant assumption that we were somehow unaware of sizeof's classification, is simply bizarre.
    Second, if the 'concept' of what is passed when you give an array as an argument doesn't change in the call, then there would be no cause for the behaviour of sizeof to change, would there? Yet change it does, and the consequences of this are important for C learners to understand when passing arrays around.
    I note you casually gloss over what *actually* happens when you attempt to use sizeof on an array function parameter, and worse you imply that people sometimes even do it in practical code (spoiler alert - they do not).
    Note to any students here: the result will at best confuse you, and at worst mislead you (like our host here), because even though the parameter is declared as an array in the prototype, it is treated as a pointer in the function body. sizeof will give you the size of a pointer (likely 4 or 8) for that parameter, not the size of the same array type were it declared as a local variable. The actual size must be known by other means if not hard-coded (either another parameter, or a sentinel value in the array).
    Which is a shame, because being able to call sizeof on an array is actually very useful (contrary to our host's attempt to downplay it) when doing things like calling memcpy, or to calculate the number of elements (sizeof (y)/sizeof (y[0])) for loop bounds, in order to avoid having to worry about whether you changed all your 6's to 7's in your code when you added that additional element to your initialiser.
    Just be aware that it doesn't work on function parameters, regardless of what the function prototype might lead you to believe, because at that point you're really just working with a pointer.

    • @mensaswede4028
      @mensaswede4028 หลายเดือนก่อน +6

      This is just drivel, and is far more likely to confuse to the target audience of this video than what is actually said in the video. The author’s point is that sizeof happens at compile-time, not at runtime, so it’s appropriate to describe it more like a compile-time operator than a runtime function, which is helpful to a beginner trying to understand what’s going on.
      And the author is correct that nothing “happens” to an array when a program calls a function and passes that array as a parameter. The array is ALWAYS nothing more than an address AT RUNTIME. However, the array variable was indeed much more than just an address at compile-time, which is why sizeof(declared_array_variable) returns something different than taking the sizeof that same address after its been passed to a function. Understanding that sizeof is a compile-time operator explains why you get these two different answers from sizeof. It’s because at compile-time there is a big difference between an array and a pointer, and sizeof is a compile-time operator. At runtime there is no difference- it is just an address, but sizeof is not a runtime operation.

    • @toby9999
      @toby9999 หลายเดือนก่อน +4

      My observation is that he labours too much on the "array is an address" thing. I'm not sure why he does that. Everything is addresses at the CPU. Fetches, stores, jumps etc. A pointer is a variable that contains an address. An array name is an address pointing to a block of data. An array name can be cast to a pointer and both will point to the same memory block. There's that whole thing about sizeof which isn't that difficult to grasp.

    • @FraggleH
      @FraggleH หลายเดือนก่อน +2

      @@mensaswede4028 First, you are simply incorrect about the compile-time v runtime thing. sizeof has the exact same *behaviour* when the operand is a VLA, which by definition *has* to be computed at runtime.
      But it's also weird that you're making my point for me. An array is not a pointer, absolutely, yet Huw is explicitly saying an array is nothing more than a pointer with his statement that "An array *is* an address" (a statement that can far more credibly be made about a pointer).
      If I'm being charitable to Huw, I think he was originally trying to point to the fact that because the C standard doesn't require compilers to maintain information about the size of an array object at runtime beyond the scope it was declared in (and explicitly denies the availability of that information at the function boundary) that in practice implementations do not store it at runtime (VLAs notwithstanding) and that could then be linked to the curiosity that in C, arrays can undergo arithmetic as if they were pointers and pointers can be indexed as if they were arrays.
      But leading off with some conceptual nonsense that in C 'an array *is* an address' is just setting people up for trouble down the line.
      I wasn't even going to comment any further on this until he then piled on even more misinformation (e.g. on how sizeof on an array is used in practical code) in some strange attempt to save face.
      But it is what it is and this is the internet, people can make their own judgements from here.

    • @FraggleH
      @FraggleH หลายเดือนก่อน +2

      @@toby9999 Indeed, he's turning an implementation detail into an unnecessary conceptual claim, that actually obscures the useful information, in my opinion. I do get, though, that maybe more discussion on this point isn't going to help anyone now.

    • @mensaswede4028
      @mensaswede4028 หลายเดือนก่อน +1

      @@FraggleH Well I’ve changed my mind. You’re not just writing drivel, you actually don’t know what you’re talking about. But as you said, arguing on the internet is pointless and people gonna believe what they want.