Triple Ref Pointers - Computerphile

  Рет қаралды 149,111

Computerphile

Computerphile

6 жыл бұрын

The 'magic' trick of pointers to pointers - Professor Brailsford explains how what might seem complicated will actually simplify your code. (See Extra Bits video for a code walkthrough)
The Professor's Code: bit.ly/Computerphile_ProfBrail...
EXTRA BITS - Triple Ref Code: • EXTRA BITS: The Triple...
n.b. Message from the Prof: Many thanks to all of you who have pointed out that I got over excited at the end of this video and (on the LEGO model) did the pointer reassignment in the wrong order. The correct way ( in the model once again) was to do the short pointer first and the longer pointer second - which I think is done correctly in the downloadable C program.
/ computerphile
/ computer_phile
This video was filmed and edited by Sean Riley.
Computer Science at the University of Nottingham: bit.ly/nottscomputer
Computerphile is a sister project to Brady Haran's Numberphile. More at www.bradyharan.com

Пікірлер: 400
@profdaveb6384
@profdaveb6384 6 жыл бұрын
Many thanks to all of you who have pointed out that I got over excited at the end of this video and (on the LEGO model) did the pointer reassignment in the wrong order. The correct way ( in the model once again) was to do the short pointer first and the longer pointer second - which I think is done correctly in the downloadable C program.
@juanok2775
@juanok2775 5 жыл бұрын
ProfDaveB your videos are awesome!
@josevSang
@josevSang 4 жыл бұрын
i love listening to you, even when am not getting anything
@oysteinsoreide4323
@oysteinsoreide4323 4 жыл бұрын
I guess it was the fun of having a long lego pointer that got you off track :p. Very nice videos that also is nice not just for beginners, but also people who have been programming for a while.
@NEDinACTION
@NEDinACTION Жыл бұрын
I watch these videos because of how excited you are! Your excitement shows through and makes them both entertaining and informative. If the cost of that is the occasional minor inaccuracy I'll take it.
@Rohith_E
@Rohith_E 3 жыл бұрын
"All problems in computer science can be solved by another level of indirection except for the problem of too many layers of indirection." - Fundamental Theorem of Software Engineering
@hexdev
@hexdev 6 жыл бұрын
I must say, this video was..... on point.
@C4rb0neum
@C4rb0neum 6 жыл бұрын
As a CS student I must admit that I lauged at "well, by the principle of colored lego type theory ..."
@cirnet
@cirnet 6 жыл бұрын
6:00 - "And look! Look what you can then do, is you start with Tracer, you jump to that box, but then, you jump down the fireman's hose and you can take a look and you see that the next thing is chips. And you say WOWWWW! I've just seen beer! I'm looking ahead by this sneaky technique and I see chips, that's where I belong! I want the burger thing in there!" Somebody please please please make an animation for this voiceover PLEASE!
@ambiorixbelgae9768
@ambiorixbelgae9768 6 жыл бұрын
hahaha
@tonaxysam
@tonaxysam 2 жыл бұрын
Yes
@marcvanleeuwen5986
@marcvanleeuwen5986 6 жыл бұрын
Very nice. I'm old enough to have grown up with Algol68 too, where I was taught this. I've occasionally used it as well, even in C++ (where using singly linked list is somewhat out of fashion, shame). The video forget to explain the "triple" in the title, so let me add that. In Algol68, the essence of a reference is the ability to modify what is referred to, which implies that pointers are references, but also that having a simple modifiable variable, say of type int or real, already involves a level of reference (the variable itself has mode REF INT when its value has mode INT). Then the variable 'tracer' that holds a pointer to pointer to NODE has mode REF REF REF NODE (while at each instant the pointer-to-pointer value it holds has mode REF REF NODE).
@ChrisWalshZX
@ChrisWalshZX 6 жыл бұрын
Surely the way you explained this, there is no real difference between using a pointer to a pointer to the object (which can point to any blue box) than using a pointer to the object containing the next pointer? You can still follow the hoses to the next item in both cases. I think the *real* key point (excuse the pun!) that has been missed in this video is that a "pointer to a pointer" can point to the address of the *start pointer* and correctly insert an element at position 0 without treating it as a special case (because you can update the "start pointer" in just the same way as you can update any of the "next pointers" of the preceding element. This should have been made much more apparent as many will have missed that subtle point (again, sorry no pun intended). Shame because it was otherwise a great explanation.
@error.418
@error.418 6 жыл бұрын
This allows you to use one pointer with what is actually called multiple indirection instead of two pointers. So it saves some memory. Today this memory savings is not significant, generally. But in specific applications, such as embedded controllers, it can be very valuable.
@1323545624
@1323545624 6 жыл бұрын
Does it also help at the end? Looking whether a pointer is null would be save vs trying to follow a null pointer?
@ayyubshaffy3612
@ayyubshaffy3612 4 жыл бұрын
he made that POINT in the first video , this is a follow up video
@sidkapoor9085
@sidkapoor9085 2 жыл бұрын
watch the unlisted vid in the dscription.
@BacklogWarrior
@BacklogWarrior 6 жыл бұрын
For those asking why not just use doubly linked lists -- imagine programming in the early 70's. You could likely be creating software for machines that have less than 1MiB of RAM! If you wanted to manipulate or process large lists, where the size of a pointer on a 16-bit computer could be 2 or 4 bytes each, it would be very important to conserve space in memory by restricting yourself to singly linked lists -- which is how this pointer technique would come in handy. Of course, now we have the luxury of computers that come with many GB of RAM, and high level languages that abstract away things like pointers, so the usefulness of a technique like this can be hard to understand right away.
@DaveWhoa
@DaveWhoa 6 жыл бұрын
I want nothing to do with a language that doesn't allow pointers. Extra GB of RAM or faster CPU is no excuse for inefficient code.
@error.418
@error.418 6 жыл бұрын
+Dave Smith That's a problematic stance. Pre-optimization is a common pitfall. Also, it's much easier to speed up clean code, than to clean up unreadable "efficient" code. You have to allocate your time and effort, and optimizing all code is a poor decision. Instead, you optimize the bottlenecks that you observe after writing the code, or areas where there is increased user demand. When you encounter an issue, you let the backpressure of that problem dictate where to optimize. Otherwise you end up creating more problems and much harder to maintain code. Pointers are also not necessary for most optimization needs.
@retropaganda8442
@retropaganda8442 6 жыл бұрын
Linked list aren't memory efficient to begin with.
@ScootrRichards
@ScootrRichards 6 жыл бұрын
Retropaganda - Every form of data structure starts internally with a linked list. The links may be abstracted so the coder doesn't have to deal so much with maintaining the link, but they're still there. The only alternative is the much more primitive "unlinked list" - also called an array. Arrays are much less efficient at organizing data - it's more expensive to move all the data than just change a link - and is more error prone. Moden languages hide the details of how the data are linked, or present it as a structure that is more relevant to the information represented, but those links are still there.
@mauriciocortazar9604
@mauriciocortazar9604 5 жыл бұрын
@@retropaganda8442 of course they aren't, but is there a better approach?
@Clouds095
@Clouds095 6 жыл бұрын
This is actually used in the Linux kernel for lists.
@profdaveb6384
@profdaveb6384 6 жыл бұрын
Fascinating! People who delve into Operating System code have to be *totally* happy about pointers ...
@conorgiles
@conorgiles 6 жыл бұрын
And suddenly I understand pointers at a whole new depth. I understood them from a technical standpoint, but this here actually helped me understand some of the subtleties that make pointers so powerful a tool. Thank you!
@adityasadawarte2532
@adityasadawarte2532 4 жыл бұрын
I have been using C for the last 3 years and never understood the pointer to pointer concept. In fact, I was always afraid of it. After watching Linus Torvalds's TED talk, I was still very confused. Thank you Dave, for making me comfortable with triple reference. This has been the best explanation. Period.
@OneMilian
@OneMilian 6 ай бұрын
Definetly relateable. I don't use pointers, except there is a reason.
@custard131
@custard131 6 жыл бұрын
love the lego demonstrations. but i did find myself struggling to think of where a solution like this has advantages over alternatives (double linked lists, tree structures, arrays)
@jamesmiller6882
@jamesmiller6882 6 жыл бұрын
I don't think I've ever heard somebody get so excited about pointers before and it's awesome.
@Antolish
@Antolish 6 жыл бұрын
Technically, last two steps should have been done in revers order. We need to first make burger's next pointer point to chips, and then make the dereferenced tracer (aka beer's next pointer) point to burger. But it's a cool technique if there ever was one.
@goininXIV
@goininXIV 6 жыл бұрын
7:19: "Do the long one first" If you do that, don't you lose all reference to "Chips" and would no longer be able to know what "Burger" should point at? Afaik, the pointer from Burger to Chips should always be constructed first, shouldn't it?
@stensoft
@stensoft 6 жыл бұрын
You need to remember it somwhere before changing it, yes, but it can be in some temporary pointer. In an efficient code, you would indeed do it your way.
@_valxp
@_valxp 6 жыл бұрын
Yes, he should have done it the other way around first to avoid the need of a temporary pointer. burger.next = *tracer; // Set the next reference of burger to point at chips *tracer = &burger; // set the next reference of beer to point at burger
@slavkosster
@slavkosster 6 жыл бұрын
burger.next = *tracer.next
@_valxp
@_valxp 6 жыл бұрын
@slavkosster Tracer is a pointer to the pointer of beer.next. So it should be burger.next = *tracer; He says it here: 4:46
@slavkosster
@slavkosster 6 жыл бұрын
yes, sorry, of course :D I always got confused with pointers and I haven't coded with pointers in years.
@samarthtandale9121
@samarthtandale9121 11 ай бұрын
These videos are tremendously interesting and helpful !!! Thank you so much ... !
@profdaveb6384
@profdaveb6384 6 жыл бұрын
If you follow the link to EXTRA BITS, in the Info block of this video, you'll find that I've posted a comment there explaining why the 'triple ref' naming of this trick made a lot of sense in the Algol68 version, which was where I encountered it in the early 70s. There's also more details about the downloadable C version of the code.
@error.418
@error.418 6 жыл бұрын
The "triple ref" name is perfectly understandable and fine as a piece of history. But it's important to use the currently accepted name for this, too. Otherwise it somewhat inhibits the learning process. This language feature is called "multiple indirection."
@mohanenb7965
@mohanenb7965 5 жыл бұрын
Damn, I really love the way how this guys explains
@orion8369
@orion8369 6 жыл бұрын
This is probably the best illustration of a linked list I've ever seen.
@kadlubom
@kadlubom 6 жыл бұрын
I love the NULL lego ;)
@stensoft
@stensoft 6 жыл бұрын
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.
@BeCurieUs
@BeCurieUs 6 жыл бұрын
Oh gosh, how did I miss that, lol, awesome!
@ricardoabh3242
@ricardoabh3242 6 жыл бұрын
Maciej Kadłubowski Falcon! In a few day
@toasty8
@toasty8 6 жыл бұрын
Isn't it a VOID lego?
@wlan246
@wlan246 6 жыл бұрын
The last blue lego in the chain is a pointer to the same type as all the others. ("void" is a type; "null" is a value.)
@babel_
@babel_ 6 жыл бұрын
So let me get this right. First, we use Tracer. Then we blink forward to see if we've gone too far and, if we have, then we rewind to where we just were. Seems simple enough.
@CJSwitz
@CJSwitz 6 жыл бұрын
Hahahah. If I might add a correction, you blink forward twice to check, then rewind, blink forward once, and change your direction.
@npc6924
@npc6924 6 жыл бұрын
Alex Blandin the problem lies in blinking forward, but then not being able to rewind. This leads to many fatal errors.
@OpenGL4ever
@OpenGL4ever 5 жыл бұрын
It's more like doing measuring a rock with a laser without the need to touch the rock physically in the first step. In other words, your robot doesn't have to move in the first step.
@Yotanido
@Yotanido 6 жыл бұрын
One of the main advantages that appear to have forgotten to be mentioned is that inserting at the front is no longer a special case. If you only use pointers to things, you have to check if you are inserting at the front of the list to modify your "start" pointer. However, if you use a double pointer, you can point it at the start pointer and say "insert this". If it happens to be at the front, it will just replace the start pointer like it was any other pointer. And to all those people saying you can just use normal pointers: Yes, you could. Using a double pointer results in much simpler code, though and arguably describes more closely what was intended.
@profdaveb6384
@profdaveb6384 6 жыл бұрын
Exactly! Well said.
@ChrisSeltzer
@ChrisSeltzer 6 жыл бұрын
This is such a cool video series.
@jtsiomb
@jtsiomb 6 жыл бұрын
My favourite technique for this kind of insertion is to just always work with node->next. To avoid having special cases for the first node, I simply make a dummy node as a local variable that points to the first node, and start the iteration from there. At the end of the loop just assinging head = dummy.next; is sufficient to handle insertion at the head of the list without special cases.
@sidkapoor9085
@sidkapoor9085 2 жыл бұрын
so you are basically making the head node second in the list.
@HarmelodicOld
@HarmelodicOld 6 жыл бұрын
That's pretty freaking cool and powerful. As a programmer who codes in higher level languages, it's super interesting knowing this lower level stuff :D I've gotta jump into C, it's brilliant! Also, naming it a TRIPLE reference pointer where you have the pointer then the "double" pointer to pointer, it's a triple. Nice one programmers. Just pushing the "arrays start at zero" agenda :D
@Dragon-Slay3r
@Dragon-Slay3r Жыл бұрын
Nice pointer they used the curve mantis to catch the S while the skinny mantis could make a different stand to confuse the pointers
@hoagy_ytfc
@hoagy_ytfc 6 жыл бұрын
Ha, I used the Malvern Algol 68 compiler on Multics machines when doing my first degree in 1980-4. Happy days. I loved Algol68 at the time.
@TheHighlander71
@TheHighlander71 6 жыл бұрын
Wonderful explanation.
@OranCollins
@OranCollins 6 жыл бұрын
Do a tree data structure! This made so much more sense thank you guys
@abrorabyyu6221
@abrorabyyu6221 10 ай бұрын
i am learning a lot, thanks prof
@kim15742
@kim15742 6 жыл бұрын
Oh, references to pointers have been so useful for me!
@autolykos9822
@autolykos9822 6 жыл бұрын
Any design problem can be solved by adding another layer of indirection - except for too many layers of indirection.
@AndyTurfer
@AndyTurfer 6 жыл бұрын
Excellent explanation - very clear and concise. Using the lego blocks to visually show how it works was brilliant (even though pointer reassignment was in the wrong order)! I know the downloadable sample code provided is just for learning purposes, but I'd just like to point out that in function PrintList(), there's no need for the "head" parameter to be a pointer-to-pointer-of-THING, as PrintList() will not be modifying anything (it just traverses the linked list and prints out "item" from each THING node). In my humble opinion, you could simplify things in this case by using pass-by-value for the "head" parameter instead: void PrintList(const THING *head) { const THING *tracer = head; while (tracer) { printf("%s ",tracer->item); tracer = tracer->next; } } This would then be called from within main() like so: PrintList(start); NOTE: I've made the "head" parameter and "tracer" constants. This will prevent things like: tracer->next = NULL; // item); tracer = tracer->next; } }
@profdaveb6384
@profdaveb6384 6 жыл бұрын
Yes I agree that tripleref is somewhat overkill for 'printlist' On the other hand tripleref does make the RemoveThing routine rather more elegant than doing it the "traditional" way.
@Lawa9919
@Lawa9919 6 жыл бұрын
cheers love, the pointerpointer is here!
@VoilaTadaOfficial
@VoilaTadaOfficial 6 жыл бұрын
I was looking for this comment.
@lucianodebenedictis6014
@lucianodebenedictis6014 6 жыл бұрын
Lawa9919 I knew it!
@error.418
@error.418 6 жыл бұрын
Heh, it's a pointer that uses multiple indirection: en.wikipedia.org/wiki/Pointer_(computer_programming)#Multiple_indirection
@shashanksharma21
@shashanksharma21 4 жыл бұрын
Absolutely brilliant !
@aryanchatterjee1514
@aryanchatterjee1514 3 жыл бұрын
Drinking game: take a shot every time prof dave says pointer
@newroosterlouis
@newroosterlouis 6 жыл бұрын
It seems that you also have the added benefit of always having the start address as well and leaving that unaltered.
@brucelytle1144
@brucelytle1144 Жыл бұрын
Nice explanation! I had a problem to solve one time that required at times a *****char[] to point to my data. It drove my (1988 Microsoft C) compiler (and me) crazy trying to figure out how to write it so the compiler stopped gagging!
@RuySenpai
@RuySenpai 6 жыл бұрын
Love how I just got assigned to program a list.
@StreuB1
@StreuB1 6 жыл бұрын
I have absolutely no idea what they are getting on about, but I do enjoy watching anyway.
@davidgillies620
@davidgillies620 6 жыл бұрын
I didn't know this was called a triple ref pointer. But seeing something like p->next->next in C linked list code is pretty common.
@triularity
@triularity 6 жыл бұрын
I learned this technique from browsing through XWindows server code around the early-mid 90s. I didn't know what, or if, there was any real name for it, so in my code I referred to it as pnp (Previous 'Next Pointer'). Technically it may have been more accurate to name it ppnp (Pointer to Previous Next Pointer), but that was a little too wordy.
@OpenGL4ever
@OpenGL4ever 5 жыл бұрын
Why not just pointer to previous next? Or in short ppn.
@bibekgautam512
@bibekgautam512 5 жыл бұрын
How is it different from say keeping a backup of the start pointer so you don't lose where the list starts as you traverse down the list to or remove things?
@martinmarcos5763
@martinmarcos5763 6 жыл бұрын
I think Ada 2012 can do triple ref. The pointer equivalent in Ada is the Access. Accesses are safer than C pointers since they are strong typed and casting is prohibited by default. When casting is absolutely necessary you can use the "Unchecked_ Conversion" package, but should be used with the utmost care. Great channel and vids, keep it up!
@profdaveb6384
@profdaveb6384 6 жыл бұрын
Thanks for this. I forgot to mention ADA. But I think you're right: ADA can almost certainly do it.
@rogeurroger7119
@rogeurroger7119 4 жыл бұрын
I wish my math teacher was like him. I'd have been so much more into science!
@gaskelldave
@gaskelldave 6 жыл бұрын
It's maybe already been mentioned but I remember programming the Mac 68000 or perhaps a G3 series in C and there were pointers to pointers used for various OS calls or memory allocation which according to the Mac programming book I used were called "handles". Is the Mac alone in calling pointers to pointers handles?
@speedbump0619
@speedbump0619 6 жыл бұрын
A handle is, more generally, a value which represents some specific "thing", but you aren't intended to do anything other than use it to name that specifc "thing" when requesting further operations involving said "thing". A handle might be a pointer (typically to an object you don't know the structure of), but it could be an array index (the unix 'open' returns a file 'handle', which is almost always an index into a table of open files), or some kind of hash/secret key.
@wicpar
@wicpar 6 жыл бұрын
Double linked lists are the way to go nowdays, those allow for facilitated traversal with only 8 bytes more, but if you dislike wasting memory, you can implement it with a xored pointer system. It may be interresting to present those
@christianbeaumont5318
@christianbeaumont5318 6 жыл бұрын
The way to go nowadays is the same as it ever was and to use the most efficient data structures and algorithms to match the required use case, anything else is lazy and the reason many applications are way slower than they need to be. "Oh, I'll just throw an extra 8 byte pointer in each list node", at least to me is a very bad attitude to spread. That 8 bytes may not seem like much, but it has huge downstream effects on busting your very limited space cache hierarchy; and the way you should think about "reaching out" to main memory is to avoid it like the plague. When in doubt, consider main memory as the new "Hard Drive" and SSD as the new "Cassette Tape" Sorry for the rant, but I downloaded a PDF reader the other day that was 640MB in size! A PDF READER! So yeah, excuse me if I'm a bit touchy on the topic. Xor'd pointers otoh is a very neat trick!
@Zadster
@Zadster 6 жыл бұрын
Good to see Donald Knuth's Art of Computer Programming on the bookshelf!
@sabrinnnaaaaaaa
@sabrinnnaaaaaaa 6 жыл бұрын
so if you wanted to go up multiple levels would you need a dedicated link to the start?
@yaerius
@yaerius 6 жыл бұрын
I'm a simple man. I see LEGO I click.
@yaerius
@yaerius 6 жыл бұрын
fuckwad wow, so insightful of you. and your sense of humor, outstanding. you should definitely listen to your own advice written on your profile image.
@error.418
@error.418 6 жыл бұрын
Don't take trolls personally, it's just dry humor
@Eden-jp4hy
@Eden-jp4hy 6 жыл бұрын
Love this guy
@imhafdhom
@imhafdhom 6 жыл бұрын
Cool data structure lesson :-D
@dominiquefortin5345
@dominiquefortin5345 6 жыл бұрын
You can also use an extra node at the end of the list that you use as a terminal node with no payload (a caboose). Then when adding a new node that should go before the node you are pointing at, you insert it after the exchange payload. And Voila! It's faster but you need an extra node for each list.
@speedbump0619
@speedbump0619 6 жыл бұрын
Yes, in theory. With care this can be done without an extra node (essentially special case code for end of list. This doesn't work for any use case where the node address is used elsewhere or if it's expensive or impractical to "relocate" the data field (intrinsic lists for instance).
@user-or7ji5hv8y
@user-or7ji5hv8y 5 жыл бұрын
So is the power the ability to look two steps ahead while retaining the point of reference?
@reecescott3559
@reecescott3559 5 жыл бұрын
Wow. The person who filmed this at 8:13 was my teacher in secondary school
@peterjansen4826
@peterjansen4826 6 жыл бұрын
Explaining pointers with Lego. Well done, professor. It made clear why you would use pointers to pointers, something I didn't get with that introductory programming (C/C++) course which I got. It is about making it easier to implement a link in the chain. Next time vegetarian please given whole that biomass pyramid and world hunger problem. ;) I can't believe that this channel about software gets so many subscribers. What percentage of the people can program at least a little bit? 10%? The internet never seizes to amaze, does it?
@vo1d42
@vo1d42 Жыл бұрын
I was able to come up with a recursive approach to reserve a linked list using triple ref pointers. void reverse(Node** head) { if (*head && (*head)->next) { Node* rest = (*head)->next; reverse(&rest); (*head)->next->next = *head; (*head)->next = NULL; *head = rest; } } But it's not much different than using simple pointers: Node* rev(Node* head) { if (!head || !head->next) return head; Node* rest = rev(head->next); head->next->next = head; head->next = NULL; return rest; } head = reverse(&head);
@ClevelandBrowns32
@ClevelandBrowns32 6 жыл бұрын
I LOVE THIS!!!!
@xdevs23
@xdevs23 6 жыл бұрын
Pointers are great!
@platin2148
@platin2148 6 жыл бұрын
For example a CString Array made out of pointers to pointers because strings in c are char* and an array of strings are char* variable_name[] or char**.
@jamlaminnswordhand5402
@jamlaminnswordhand5402 6 жыл бұрын
I was looking for something referencing that. Or maybe dereferencing? ;) I'll see myself out.
@Tasarran
@Tasarran 2 жыл бұрын
Kind of interesting that this video is less than half the length of the previous one... Like he says, it looks like it would complicate things, but simplifies them...
@johnvictor9071
@johnvictor9071 6 жыл бұрын
So how about doubly linked-lists? Where one pointer points to the next object, but another points to the prev object.
@stensoft
@stensoft 6 жыл бұрын
They are a possibility but they take additional space for the second pointer
@BeCurieUs
@BeCurieUs 6 жыл бұрын
With double linked list, you have a link looking backwards as it is, this technique isn't needed . The reason we need this technique is precisely because we don't have a look back pointer!
@seigeengine
@seigeengine 6 жыл бұрын
To clarify, in a singly linked list, you only need to use an extra pointer when you're inserting something into the list, which temporarily uses a negligible amount of extra memory, but in a doubly linked list, every single item in the list gets another pointer, which increases the overhead of the structure. This is probably negligible in the majority of cases, sure, but it's a drawback for sure.
@NeilRoy
@NeilRoy 6 жыл бұрын
You have two single pointers in that case. They are not pointers to pointers. Each of the pointers in a doubly linked list points to either the next object, or the previous object. A pointer to a pointer is something that points to another pointer. So you're getting the address of another pointer, which in turn points to a variable or object of some sort.
@error.418
@error.418 6 жыл бұрын
It's technically called multiple indirection: en.wikipedia.org/wiki/Pointer_(computer_programming)#Multiple_indirection
@avitachna-fram6675
@avitachna-fram6675 5 жыл бұрын
Whats the advantage of this implementation versus just using two iterators, one pointing to the the nth element and one pointing to the n+1th element?
@pixelstormnetwork
@pixelstormnetwork 5 жыл бұрын
On a 16 bit machine, it saves two bytes of RAM. And you can update the start pointer when inserting an element at the front of the list.
@Spongman
@Spongman 6 жыл бұрын
the two pointer method is more efficient, though, because you don't have to deference memory twice for each item - you just shuffle your prev/next points around which can be done with register renaming without a stall.
@speedbump0619
@speedbump0619 6 жыл бұрын
Every optimizing compiler will turn the double indirection method into optimal register stores, so nothing is lost. However, if your platform happens to be register constrained this method is likely to still generate optimal instructions (particularly for platforms with fast double indirection instructions).
@dstarfire42
@dstarfire42 4 жыл бұрын
For the other non-programmers puzzled by the term 'dereference' it simply means we're going to follow this 'pointer to a pointer' (the lego chain) and STOP. We're not going to follow down the link of the pointer we've arrived at (the black lego hose), we're going to look at the pointer itself. In this example, that's how we know we're at a thing with the value "beer". If we were to follow the pointer we arrive at a thing with the value "chips".
@benjamingeiger
@benjamingeiger 6 жыл бұрын
Do we really need a separate variable for this? If we have a pointer *cur pointing to a node, can't we simply look at cur->next->data, instead of having a pointer *tracer that happens to point to cur->next? Maybe I'm missing the point here, no pun intended.
@erikmihalj
@erikmihalj 6 жыл бұрын
Yes we can and we are. 8) This "tripple" pointer thing is bs.
@Maver1ck101
@Maver1ck101 6 жыл бұрын
What do you mean? Can you post the equivalent code for your approach, please?
@benjamingeiger
@benjamingeiger 6 жыл бұрын
On my phone, so pseudocode: thing *cur; thing *ours = [the value to insert] cur = head; while (cur != NULL) { if (cur->next == NULL || cur->next->data > ours->data) { ours->next = cur->next; cur->next = ours; break; } }
@Maver1ck101
@Maver1ck101 6 жыл бұрын
@Benjamin, there are a few issues with your (pseudo)code: 1. You've got no code to actually traverse the list; you could add `cur = cur->next;` after the `if` statement. 2. Your code will fail to add any node (i.e., THING) at the front of the list. Think about what happens when I pass an empty list to your function. The `while` loop test will fail and your function simply exits. You can fix this issue by adding the following two lines after the `while` block: newp->next = head; head = newp; 3. Even after fixing those two issues described above, you run into the biggest problem of them all. Any changes you make to `cur` inside this routine will not get reflected in the caller (i.e., calling function). This is because `cur` is local to your routine and gets "destroyed" when it stops executing. Remember that `head` in this case receives a copy of `start` and not `start` itself. This is called "passing by value". If you suspect that the head of the list might change, it's better to pass a pointer to the head pointer rather than the head pointer itself, which is what Prof. Brailsford has done. This is called "passing by reference". This is a standard technique in C -- if you want to change a value of interest, pass a pointer to it. With your approach, no matter how much you modify `cur` and `head` inside the routine, the variable `start` does not get affected.
@benjamingeiger
@benjamingeiger 6 жыл бұрын
The first two are easy to explain: I'm currently evacuating because of Hurricane Irma, so I'm on my phone. Also, when I wrote my comment I had been up about 24 hours. As far as your last point goes: the professor appears to be using the "dummy head" technique. That is, the first node is a proper node, but it has no data. This means pointers to the head of the list never have to change. Yes, cur is a local pointer, but that's okay because it's just used to scan the list. cur disappears, but cur's referent doesn't.
@desmondbrown5508
@desmondbrown5508 6 жыл бұрын
This expanation is probably a bit confusing for new programmers (as pointers usually are). In essence what he is saying is that because a pointer can dereference to a value, a double (he called it triple) pointer can dereference to addresses (and go do so twice). This means the first dereference will give you the address of the 'burger' and the second dereference will give you the address of chips. And you can cast (*) on either address given to get it's value.
@NeilRoy
@NeilRoy 6 жыл бұрын
A good example of pointers to pointers that is most commonly used is a string of text. You are pointing to a list of pointers that each point to a single character.
@xybersurfer
@xybersurfer 6 жыл бұрын
Neil Roy no. in C, a string is just a pointer to a character. the characters are stored next to each other in memory (they are an array). to get a pointer to the next character you can increment the pointer to the character using: p++; or you could cast it into an array and use an index on this array, to get the character you want: c = arr[i] because arrays in C are basically pointers
@christianbeaumont5318
@christianbeaumont5318 6 жыл бұрын
Haha, I don't know if you were joking, but a string like that would be really funny. It would take O(1) time to change all the E's to I's, and O's to U's, how marvelous!
@speedbump0619
@speedbump0619 6 жыл бұрын
Think about how efficient substitution cyphers would be!
@JoshuaHillerup
@JoshuaHillerup 6 жыл бұрын
Can you do something comparing standard link lists with the kind that Haskell uses where it's basically backwards?
@marcvanleeuwen5986
@marcvanleeuwen5986 6 жыл бұрын
Not clear to me what you are asking. Though Haskell certainly uses pointers internally, the user does not get to see or manipulate them, so I cannot see how anything like this would apply there. Besides, this kind of insertion by pointer manipulation is inherently imperative, so would not apply in Haskell. In Haskell if you insert something in the middle of a list, the whole beginning of the list is copied to new nodes, only the unchanged tail can be shared with the original list.
@xybersurfer
@xybersurfer 6 жыл бұрын
Joshua Hillerup i think they are exactly the same. it's more convenient to insert something into the front of a singly-linked list than into the back, because inserting into the back would require going through the whole list. so people tend to keep these lists reversed as long as possible so they can insert things into the front efficiently. that's why you see a lot of reversed lists. usually people reverse the list when they are done, to give it the correct order again. the exact same problem exists with the singly-linked lists in this video
@kayvee256
@kayvee256 6 жыл бұрын
@3:00 Cheers love, the cavalry's here!
@nonreviad
@nonreviad 6 жыл бұрын
I believe that programmers not knowing this technique for inserting an element in a linked list is one of Linus Torvalds' pet peeves.
@sabriath
@sabriath 6 жыл бұрын
Just to note, this technique has less concern with "keeping half a finger on previous," because the same technique of "peaking at the next in the list" is compiled in EXACTLY the same way as a double pointer mechanic. It literally boils down to typecasting to help the programmer, but meaningless at the assembly level. I've never come across a need to create a double pointer except with dynamic 2D arrays.....and that's pushing it.
@AbdulelahAlJeffery
@AbdulelahAlJeffery 6 жыл бұрын
in the case of inserting at the head of a linked list, either I'm missing the point or this is unnecessarily complicated! what's wrong with pointing 'start' to the new THING, and point the new THING to the previous head of the linked list? only two pointers update
@trevinbeattie4888
@trevinbeattie4888 6 жыл бұрын
Without the additional indirection, inserting an object at the head of the list would require completely different code than inserting it in the middle. More importantly it couldn't be done by a subroutine call without passing a pointer to 'start' in case the start has to change.
@greywolf271
@greywolf271 6 жыл бұрын
so what's the difference between this and a linked list ?
@xybersurfer
@xybersurfer 6 жыл бұрын
very interesting code. i didn't understand how intuitive it was until i saw it. but it has some issues
@ctuchikAO
@ctuchikAO 6 жыл бұрын
What about some concurrency mental gymnastic with LEGO for the next episode?
@nikanj
@nikanj 6 жыл бұрын
Word has it Professor Brailsford drove around to 5 shopping centres to find that Lego chain piece just for this video.
@profdaveb6384
@profdaveb6384 6 жыл бұрын
Sean's two boys kindly loaned various hoses and chains from their own collection of LEGO. I should also add that no expense was spared for this video. Even with the loaned hoses I didn't have nearly enough, so I had to order a dozen more from (the UK instance of) LEGO's "buy a brick" service. Cost me £25. Bankruptcy beckons !
@ambiorixbelgae9768
@ambiorixbelgae9768 6 жыл бұрын
lol
@ivarkrabol
@ivarkrabol 6 жыл бұрын
Love the video, and I'm totally being unnecessarily critical here, but I think it would make more sense within your Lego analogy to have the existing black pointer of "beer" point to "burgers", and then have the yellow pointer of "burgers" point to "chips", rather than making the existing pointer that used to go from "beer" to "chips" now begin at "burgers" instead.
@xybersurfer
@xybersurfer 6 жыл бұрын
Ivar Kråbøl i can see where why you think that. but if you see the black part going from "beer" to chips as a value pointing chips, then it is correct that it now belongs to "burgers". because "burgers" is now pointing to "chips". the yellow part is a new pointer value. i think you would have been correct if he took the blue block from "beer" and used it as the blue block for the new "burgers" thing
@ceputza
@ceputza 6 жыл бұрын
Why not just use an empty thing as the head and one pointer to check the next thing item?
@Marksman560
@Marksman560 5 жыл бұрын
Still, it''s simpler to do it without that tracer-triple reference pointer, because a linked-list is a tracer-n reference pointer from itself. (where n equals listlength) [edit] So when you loop from the start-pointer: if current pointer's object-name 'burger' insert the flippin burger (set burger-object.next-reference to current.next, and set current-object.next-reference to the burger) else set the currents pointer to the current pointer's next object, and continue the comparing of names ps Hooray for overly complex explanation :D
@frognik79
@frognik79 6 жыл бұрын
What's the point? Is it for ease of use, code readability, faster, smaller?
@speedbump0619
@speedbump0619 6 жыл бұрын
There are different types of coders and each type will answer differently. Some will approve because this eliminated extra conditional checks (so, faster & smaller), others will disapprove because this requires an additional layer of abstraction (conceptual complexity is higher). I would say if you can't get your head around this level of abstraction, maybe computer science isn't for you.
@frognik79
@frognik79 6 жыл бұрын
I can get my head around that level of abstraction among the other ways of doing things and that's why I asked the question.
@speedbump0619
@speedbump0619 6 жыл бұрын
sorry, looking back at what I wrote I sound more confrontational that I intended. What I was trying to say was that this is a level of abstraction I'd expect of any competent C coder. If it were above the level of conceptual complexity of the average coder that would be a reason to avoid it.
@AdamVanHorn
@AdamVanHorn 6 жыл бұрын
I demand more videos on "colored Lego type theory"! 😆
@OlafDoschke
@OlafDoschke 6 жыл бұрын
Nice explanation of the insertion into linked lists. Maybe the next interesting thing to show would be vectors, when I look at this lesson of Bjarne Stroustrup: kzfaq.info/get/bejne/j7ejaax0ktzLnaM.htmlm29s In essence he says that a) the linear search is bad, and what's making it so bad is the fragmentation and the rising probabilities of cache misses. On the other side, caches get bigger. As the series started with associative arrays, we already know linked lists are kept short typically anyway. To a developer rather used to 4th generation languages in my profession (I started in 6502 assembler, 68000 assembler and then also C as a hobbyist, yes, but never had to do serious assembler or C/c++ development) it is a bit of an odd discussion about the speed of access to memory organized in different ways. As a database developer, I'm also profiting of larger and larger caches and caching done even to the file level and in memory held data is a topic for sure, but it really seems like a luxurious problem of even faster RAM access with structures sorted in memory.
@DDranks
@DDranks 6 жыл бұрын
This is the Linus Torvalds trick, if I recollect correctly. He said that you don't understand pointers if you haven't got an intuitive grasp of this. (Edit: The difference here is that Linus spoke about the removing case wherease Prof. Brailsford talks about the adding case. Pointer to a pointer nevertheless!)
@rishabhshirke1175
@rishabhshirke1175 6 жыл бұрын
Video on kmp plZ
@JBaker452
@JBaker452 6 жыл бұрын
Of course, in the C language it is also easy to type-cast a pointer. Which can be as useful as it is often error prone :-)
@SpareSomeChange8080
@SpareSomeChange8080 5 жыл бұрын
This video is making me hungry
@juanok2775
@juanok2775 5 жыл бұрын
I wish he was my profesor!
@saf271828
@saf271828 6 жыл бұрын
So, here's my question: this video mentions the "triple ref" technique, but there's only two dereferences. The number of references should match the number of dereferences; so where is the third dereference coming from that gives this technique its name? FWIW, I've only known this method as the "double dereference" method.
@speedbump0619
@speedbump0619 6 жыл бұрын
foo->bar->quux = x
@ykl1277
@ykl1277 6 жыл бұрын
Never fear. The cavalries are here.
@LICHINHO
@LICHINHO 6 жыл бұрын
Very nice, but there is a mistake in the end. You have to set the link from burger to chips *before* you change the link from beer... otherwise you lose any link to the "chips" structure.
@casperghst42
@casperghst42 10 ай бұрын
Pointers are difficult until you get the idea, after that it is very easy.
@jelleverest
@jelleverest 6 жыл бұрын
Nice alternative to a doubly linked list
@diamondsmasher
@diamondsmasher 6 жыл бұрын
Or just keep two pointers, *next and *previous, while iterating.........
@MatthewWeiler1984
@MatthewWeiler1984 6 жыл бұрын
+diamondsmasher That's exactly what I was thinking.
@e995a1ad
@e995a1ad 6 жыл бұрын
The problem with the *prev pointer is that it doesn't work with the first item in the list, that you have to treat separately. The beauty of the technique presented here is that there is no special case. No "if (p == head)" needed. Might seem trivial but it's actually a big advantage. For example if you're going to create a function that works on the list, then the function doesn't need to know where the list starts, and you can indifferently pass the whole list to it, or any element within the list.
@DJjetseb
@DJjetseb 6 жыл бұрын
with a double linked list, you don't have a head unless it is a cyclic one. The only reason for a head pointer to exist is because you can't go backward in the list. So you don't check if p == head but if p->prev == null. The main advantage of double linked list is that you don't risk to loose the head with the associated memory leak and it is easier to use for some because of there is no head.
@stensoft
@stensoft 6 жыл бұрын
Actually, double linked lists have head (and tail) as well unless they are a cyclic one. Head is defined as the item with prev == NULL, tail with next == NULL. In a cyclic list, there is no head or tail, you just remember where you started.
@error.418
@error.418 6 жыл бұрын
Officially this is called multiple indirection: en.wikipedia.org/wiki/Pointer_(computer_programming)#Multiple_indirection
@raglanheuser1162
@raglanheuser1162 4 жыл бұрын
can't you just do two p's? one to reference the current pointer and one to hold the previous pointer?
@UnashamedlyHentai
@UnashamedlyHentai 6 жыл бұрын
I know it's beside the point, but a doubly linked list solves the same problem, while providing other benefits, like being able to traverse the list backward.
@trevinbeattie4888
@trevinbeattie4888 6 жыл бұрын
Not quite - when inserting a new item before the first item in the list, you still need a pointer to the 'start'. The first item's 'previous' pointer won't point there, because it has to point to an object (in this case null, since there is nothing before it,) not to a pointer.
@speedbump0619
@speedbump0619 6 жыл бұрын
If you structure things such that your head looks just like any other node then you can make doubly-linked rings which have the head node before the first real node, and after the last node. In empty lists the head "node" points to itself. In this structure you can write insertion at any location without any extra boundary checks (on either end)
@trevinbeattie4888
@trevinbeattie4888 6 жыл бұрын
So, instead of simply holding a pointer to the head of the list, you would instead hold a pointer to a fake object which indirectly points to the head of the list. Then code which traverses the list needs to be modified to check for this fake object instead of a null pointer to know when they have reached the end. Workable, but I'd have to look at some actual code to see whether this approach is more or less advantageous.
@speedbump0619
@speedbump0619 6 жыл бұрын
Given: struct LLNode { LLNode *next; LLNode *prev; }; inline LLNode *LLNode_getNext(LLNode *node) { return node->next; } struct List { LLNode anchor; }; inline LLNode *List_begin(List *list) { return list->anchor.head; } inline LLNode *List_end(List *list) { return &(list->anchor); } #define List_INITIALIZER(me) {{&(me)->anchor,&(me)->anchor}} List myTypeList = List_INITIALIZER(&myTypeList); Use is: struct MyType { LLNode node; /* whatever else you want */ }; Assume: MyType *otherInst; //to be inserted Walking the list looks something like; LLNode *node = List_begin(&myTypeList); LLNode *end = List_end(&myTypeList); while(node != end) { MyType *myInst = container_of(node,MyType,node); if (MyType_leftBeforeRight(otherInst,myInst) ) break; node = LLNode_getNext(node); } LLNode_insertBefore(node,&otherInst->node);
@HoD999x
@HoD999x 6 жыл бұрын
maybe i am overlooking something, but the entire video could have been condensed into 10 seconds
@deepjoshi356
@deepjoshi356 6 жыл бұрын
I have always checked the value of next node instead of pointer to pointer.
@stensoft
@stensoft 6 жыл бұрын
That does not work for head though because there is no node pointing to it
@Dsiefus
@Dsiefus 6 жыл бұрын
He said next: so you can go to head and look at its next pointer.
@stensoft
@stensoft 6 жыл бұрын
The issue is that it won't allow you to add before head, e.g. if you would want to add “almonds”, because there is no item pointing to the head. You could of course make a special case for that but programmers hate special cases, they make everything harder to maintain.
@RealRobotZer0
@RealRobotZer0 6 жыл бұрын
I am humbled , this was my solution: void insert(thing** tracer, wchar_t* str) { thing* t = new thing; t->item = str; while (*tracer != NULL) { if (*t next = temp; return; } tracer = &((*tracer)->next); } *tracer = t; }
@IslandHermit
@IslandHermit 6 жыл бұрын
It would be faster, less error prone and use less storage to modify the connections the other way around: set burger to point at chips first, then redirect the pointer from beer to point at chips instead.
Multithreading Code - Computerphile
15:54
Computerphile
Рет қаралды 379 М.
Wheeler Jump - Computerphile
10:54
Computerphile
Рет қаралды 82 М.
Tom & Jerry !! 😂😂
00:59
Tibo InShape
Рет қаралды 55 МЛН
Final muy inesperado 🥹
00:48
Juan De Dios Pantoja
Рет қаралды 19 МЛН
Osman Kalyoncu Sonu Üzücü Saddest Videos Dream Engine 170 #shorts
00:27
Why You Should AVOID Linked Lists
14:12
ThePrimeTime
Рет қаралды 270 М.
Where did Bytes Come From? - Computerphile
11:31
Computerphile
Рет қаралды 474 М.
Pascal (Not Just Nickel & Dime) - Computerphile
11:59
Computerphile
Рет қаралды 58 М.
you will never ask about pointers again after watching this video
8:03
Low Level Learning
Рет қаралды 2 МЛН
The Mystery of 42 is Solved - Numberphile
5:02
Numberphile
Рет қаралды 771 М.
Garbage Collection (Mark & Sweep) - Computerphile
16:22
Computerphile
Рет қаралды 235 М.
The Most Difficult Program to Compute? - Computerphile
14:55
Computerphile
Рет қаралды 1,4 МЛН
are "smart pointers" actually smart?
9:44
Low Level Learning
Рет қаралды 70 М.
Master Pointers in C:  10X Your C Coding!
14:12
Dave's Garage
Рет қаралды 284 М.
The What, How, and Why of Void Pointers in C and C++?
13:12
Jacob Sorber
Рет қаралды 51 М.
Tom & Jerry !! 😂😂
00:59
Tibo InShape
Рет қаралды 55 МЛН