10
$\begingroup$

I was reading a Q&A on Meta Software Engineering and saw some people make reference to pointers, as well as this SE. I see several Q&A here relating to pointers as well.

I don't understand why people make such a big deal about pointers. Most times I've heard about them, in school or talking to the occasional programmer, it's been made to be a big deal.

Conceptually, it's trivially trivial to understand:

Go here to get a variable. Oh, it's not the variable, it's a sticky note telling me where the variable is. OK, I'll go there instead. Goes to that other place, gets the variable. Done.

It's more difficult for me to understand why it's a Big Deal. I've never programmed where I needed to worry about them, aside from in a CS class, nor have I programmed where pointers were not how things were done.

Are pointers difficult to use in practice? Why is this a cliche topic for students? I can understand that this was a big deal when it was a new technology. But aren't most modern languages so much more abstract that this isn't a thing?

$\endgroup$
  • $\begingroup$ Pointers are basically the threshold of understanding where Concrete Operations crosses over to Formal Operations (Piaget's definitions). They are an example of the increased complexity of indirection and symbolic thinking. Some grasp easier than others, for a multitude of reasons. $\endgroup$ – Scott Rowe Aug 22 '18 at 13:16
  • $\begingroup$ When I first started programming (2002), this was one of the concepts I had a real struggle with. In honesty, I also struggled with the concept of function calls and a whole load of other stuff in the first 2 years! Now, having spent the last 12 years post-degree in a software company, pointers, "reference types", memory addresses and even arrays/lists and related concepts come naturally. But you're absolutely right to ask this question - why pointers in particular? Is this somehow a threshold of comprehension, like "the wall" for a marathon runner? $\endgroup$ – oliver-clare Sep 8 '18 at 6:47
9
$\begingroup$

This question is actually not so far off from asking why operating system memory management can be confusing to some students.

Ultimately, we only have two fundamental tools for managing memory: pointers, and calculated offsets from pointers. That's it. In spite of GypsySpellWeaver's assertion, they don't particularly support OO, they undergird literally everything.

How does the computer know what line of machine code to execute next? Pointer. How does it know where the stack frame currently is so that it can find your variable? Pointer. How does it know where the system functions are so that it can print to the screen? Pointer. Pointers are not hard at the most trivial level of understanding. They are hard because, when you actually start to look into how they are used (or manipulate them yourself), you wind up deep in the weeds in some confusing places. They are the simplistic entry point to a host of deep, rich, and complex ideas.

Here's a quick "for instance": students don't come in fundamentally understanding the stack and the heap, and without that, much of what we do with pointers doesn't make sense in the first place.

Understanding memory in a computer is not a trivial task. When I write

int z = -1

... a student naturally expects z to be a number. But, of course, it's not. It's a reference to a stack offset at which is held a series of ones and zeroes. The compiler stores z as something like stackpointer+8, and that's what gets written into the compiled code. The name z goes away.

char* x = &z + 1 is literally nonsensical, unless you understand that memory is fundamentally typeless, and what a memory address actually is. This isn't trivial stuff for someone whose whole experience with computers has been installing and using apps to play games and chat with their friends. Nor is the result of printf(x), or printf(*x).

Fundamentally, a student needs a rich mental model of the whole machine to understand pointers on anything beyond a trivially simplistic way.

$\endgroup$
  • $\begingroup$ Research backs up that assertion. Seems like a good place to start the teaching. $\endgroup$ – Scott Rowe Aug 26 '18 at 16:06
  • $\begingroup$ I won't disagree, because I've already agreed. There's one sentence, hidden in my wall of text: Technically speaking variables are an indirection, but somehow we manage to address that just fine. I believe that any concept can be apprehended with the correct mental model for it. Conversely, every concept is difficult if the metal model does not mesh with the concepts. $\endgroup$ – Gypsy Spellweaver Aug 27 '18 at 1:11
  • $\begingroup$ That backs up what I said. Everything is "fine" until someone puts the word pointer on the table. Then it's suddenly "hard" to do. If you understand memory for variables, and addresses for function calls, then pointers are just more of the same. Don't blame the student, or the concept, blame the presentation. My recent experience with pointers in C, a new language for me, empirically supports my belief. $\endgroup$ – Gypsy Spellweaver Sep 2 '18 at 13:35
5
$\begingroup$

The problem with pointers isn't at the level you have described, but in the use. In languages like Java the "reference" variables are basically pointers but the usage has been made safe via a garbage collector.

But in a language like C, in which the programmer is responsible for both allocation and deallocation of the blocks to which pointers refer, there are many traps. The two big ones are forgetting to deallocate at all, hence running out of memory in a long program, or trying to deallocate twice, causing a crash. The problem isn't easy in a complex program as the pointer variables are passed around between functions and if a block is deallocated but some pointer still points there and tries to access the block, bad things happen. Depending on the language they can be a simple crash or a run-away program.

Many attacks on systems are, in fact, the result of bugs caused by improper use of pointers.

The idea is simple enough, but the usage is complex. Furthermore, in such languages, the programmer has to solve the memory management problem for every individual program. In higher level languages, the memory management is by the system.


The reason for the importance of pointers or something like them (references) is that some program data must live longer than the lifetime of a single function invocation, hence the stack managed memory isn't sufficient. And sometimes there is so much data that static (for all time) allocation isn't efficient. Hence, values must come and go, but asynchronously with function/method invocations.

$\endgroup$
  • $\begingroup$ But sometimes people actually do not get the simple aspect of it. I can't tell you how many times my partner in the Compiler course in college declared *p and then just wrote to it. Boom! $\endgroup$ – Scott Rowe Aug 22 '18 at 13:13
  • $\begingroup$ @ScottRowe, part of that is just the denseness of C notations generally. Things that look similar, aren't. C programmers needs to keep a lot of things in their heads simultaneously. See "Miller's Rule of Seven - Plus or Minus Two". $\endgroup$ – Buffy Aug 22 '18 at 16:56
  • $\begingroup$ @ScottRowe, Java uses indirection extensively, and intensively. So do other (not all) OO languages. I assume you know that. $\endgroup$ – Buffy Aug 22 '18 at 18:26
  • $\begingroup$ @ScottRowe @ Buffy Miller's, The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information $\endgroup$ – Gypsy Spellweaver Aug 24 '18 at 18:44
  • $\begingroup$ @ScottRowe The difficulty, pointed out by this answer, is in keeping track of all the parts at once. Understanding Romeo and Juliette may not be hard, but following that script, while tending the baby, cooking dinner, planning the wedding and reaching to answer the phone, just might be a bit much to handle. $\endgroup$ – Gypsy Spellweaver Aug 25 '18 at 23:28
4
$\begingroup$

Answering "Why" people do the things they do is always a risky proposition. Be that as it may, I'll try my hand at answering your two-questions-in-one question. I believe that the answers are interdependent, with each feeding the other. This makes it hard to split this question into a pair of questions for the site, which I would normally recommend.

Why are pointers a key topic in a CS curriculum?

There a five reasons that come to mind for making pointers a key topic:

  1. They are an integral part of many of the current in-use languages, and should be understood by the students if they're going into the field as developers
  2. Pointers (whether explicitly in the foreground, or implicitly in the background) enable the Object Oriented paradigm
  3. They are perceived as difficult, and the belief is that repeated exposure, and emphasis, can pound the concept into the students' brains
  4. Understanding pointers aids in further abstract thinking
  5. Everyone else is doing it.

Integral to many of the currently in use programming languages

Many of the programming languages commonly used in software development enable pointers. They might have a different name (reference perhaps?), or their actual use can be cloaked behind other layers of abstraction. When available for use, many developers, or their supervisors, think that they must be used. Oft times their use over the basic types serves no purpose to the code or the operation of the software at all, any benefits being in the mind of the developer using them. Sometime, "because I can," or "I like them," is sufficient justification for their inclusion. Since very few of the students will transition straight from school to lead developer on a project, they will likely be working with the code of others that has a significant amount of pointer used. Working with such code will require that they have a working comprehension of pointers, their operation, and their merits, within the language of choice.

Pointer use in the Object-Oriented paradigm

I have not examined the "behind-the-scene" implementation of the OOP paradigm in great detail for any language, nor even know all the languages in which it is implemented. Nevertheless, without the ability to use pointers, by the compiler if not the code itself, I don't think OOP would be practical. It may not even be fully realizable at all without pointers. Whether or not pointers are used explicitly by the student, or the programmer, they are probably using pointers anyway. Understanding what a pointer is, and how it works, can make some of the OOP concepts easier to comprehend, and increase the facility with which the students utilize OOP in their own code projects.

Repeat the hard stuff until they "get it"

If the instructor, (or department head, textbook author, curriculum developer, etc.) believes pointers are "something people don't get" they try to make them "get it" by repeating the use of pointers in different places, across multiple courses, or from different approached. They hope is that with enough repetition, even difficult concepts will become comprehensible. If, for whatever reason, the concept presented is hard for the student, such a layered, multi-pronged approach may be helpful. If, however, the student does grasp the concept and is able to use it effectively, the repeated implications that they still don't "get it" can make them begin to question if they really do understand, or if the instructors might be correct, and they only thought they "had it" when in fact they don't. Teaching to the lowest common denominator can be just as destructive as teaching to the test.

Pointers: one layer, among many, of abstraction

Pointers are a concrete manifestation of indirection. Technically speaking variables are an indirection, but somehow we manage to address that just fine. With pointers we now have two, or more, "leaps" to get to the "data" and not only do we have to know that we have to double hop to the get data, but we also have to remember to handle the hops the right way. For example, if I do a = b where a and b are numbers, I can change the value of b and a will not change to match. If I do a = b where a and b are pointers, I can change the value of what b points to (*b = 4) and the value of what a points to (*a) will be changed as well. The syntax, or nomenclature, helps the developer keep things straight, but the develop still has to know what's happening with the pointers.

The good part is that once the student has a grasp of pointer operations, they are able to move into higher levels of abstraction with confidence. As noted in a comment by Scott Rowe above, in the computer science realms, pointers are the crossing point into formal operations from concrete operations. Crossing that threshold of understanding in any discipline develops the mental abilities to deal with formal operations, and symbolic thinking in any discipline, from computer programming to medical research and structural engineering.

Everyone else is doing it

Probably one of the most common reasons, and the worst reason because it is not a reason, is to follow the crowd, or to gain acceptance of their work. I have seen educational materials where the author attempts to present pointers, in some fashion, that end up looking like a blind person leading a deaf person into the swamps. They don't have a real grasp on pointers themselves, but try presenting them because they think their works will be judged negatively based on their mere exclusion. They could be right, I don't know. They don't seem to have a good understanding of pointers, indicating they don't consider pointers important enough to learn for themselves. Yet, because everyone else is doing it, they include an attempt at explaining pointers in their materials.


Why are pointers oft cited as something people don't get?

The claim that pointers are something people don't get, or that they are hard to understand, could be founded on any of five different reasons (or beliefs):

  1. Instructors have tried to teach what they don't understand
  2. It was hard for the instructor to grasp, so it must be hard for everyone to grasp
  3. Teachers have been warned that some people don't get pointers, so they know some of the students just won't "get it"
  4. Students, or programmers, not ready for abstraction will not "get" pointers either
  5. Everyone else is saying it's true

Passing on knowledge not possessed

If the instructor does not have a very clear understanding of pointers, it is very difficult to help the students understand them. Saying that pointers are difficult, and that some people just don't "get it" serves as an opportunity to blame the subject, and the student, for the instructor's failure.

It was hard for me, so it must be hard for you

A natural human tendency is to take our experiences and project them onto others in the form of expectations. When something was difficult for us to master, for what ever reason. we will believe that it is difficult, and will expect others to have the same difficulties. Also, how one learned about pointers the first time can have a strong influence on how they later teach them. For a general question in that vein see this old question: How is your teaching affected by how you learned?.

My (Education or CS) instructors said it was difficult, so it must be

Presuming that the instructor has been instructed in the art of instruction, the instructor's instructor could have embedded a self-fulfilling prophecy. (See Merton, Robert K. (1948), "The Self Fulfilling Prophecy", Antioch Review, 8 (2 (Summer)): 195.) If told that it is hard to teach pointers, or that students have a hard time understanding pointers, and then hearing it, or reading it, from other sources, it can become "fact" in the instructor's mind, and then acting on that "fact" in the classroom they make it hard for the students to understand pointers.

Pointers: one layer, among many, of abstraction

There are two schools of thought about abstractions. One is that the use of abstractions eliminates the need to have any concept of the processes hidden by the abstraction. The other is that abstractions are only a convenience for encapsulating processes already known, and solved, so that higher levels can be solved. In either case, if someone is not yet able to grasp the indirection and abstraction, the subject matter, already maligned, gets the credit for the student's lack of development or ability.

Everyone else is saying it's true

If it is said often enough, from many diverse corners of the field, it soon becomes common knowledge. The longer it survives as common knowledge, the more likely it is to become conventional wisdom. Unfortunately, conventional wisdom may not be all that "wise," and common knowledge may not be correct. For example, triskadekaphobia is so prevalent that many, newly constructed large buildings still do not have a 13th floor, or a usable one at least. This despite the fact that our era is supposedly enlightened and has moved beyond myths.


Are pointers difficult to use in practice? Or, are pointers hard to learn?

Pointers, in whatever guise they assume, are not difficult to use in practice, if the language supports them in a native manner. They are also not very difficult in other languages, though perhaps slightly more so than a regular variable. I have used "pointer" functionality using PEEK and POKE in BASIC in the late 70's, before I even knew what pointers were, and had no difficulties. They do not require any more diligence from the programmer than should be exercised with the rest of the code. They can, however, turn out to be a nuisance if not used responsibly. In the languages where garbage collection is not automatic it is the programmer's responsibility to track what they've done and undo it later. That shouldn't be any worse than making certain all loops have an exit condition that will happen, or that all conditions for a logic construct have an assigned branch.

Pointers should also not be hard to learn. Pointers are everywhere in our lives, and we have no problem understanding the ones outside of a program. Why, then, should they suddenly become mysterious inside a program. My phone number is a pointer, or an indirect reference, to my house: someone who knows my (1) name will look up my name in a directory listing, which lists my (2) phone number; they dial that number and someone answers the phone; they then ask the (3) person answering the phone to speak with (4) me. A very long, and complicated series of pointers that people have beed executing since before computers were built. The only excuse for pointers being hard to learn is the instructor, hopefully innocently, making them difficult. Once the concept of "variables" is apprehended, pointers, arrays, hash tables, and "complex" data structures should naturally fit in the same understanding. The more complex the structure is the more effort that is required to remember "where you put" the data. That is not because there are pointers, rather it is a factor of the quantity of elements involved. When following a route through a large city, the more turns you have to make, the greater are the chances that one of the turns made will be wrong. It has nothing to do with turning being difficult, only that a line in the instructions was skipped, or a street name misread.

$\endgroup$
  • $\begingroup$ So, where can i sign up to take a CS CLass from you? :D lol Seriously though, sounds like you know the material and how to teach and/or instruct. $\endgroup$ – YetAnotherRandomUser Aug 24 '18 at 17:17
  • 1
    $\begingroup$ @YetAnotherRandomUser I've been accused of that before, but I'm out of the education scene, and doing random solo developer projects now. $\endgroup$ – Gypsy Spellweaver Aug 24 '18 at 17:48
2
$\begingroup$

Are pointers hard? Not really. They are just virtual memory addresses. What is hard is memory management. This is illustrated by the fact that browsers, run for a period of time, develop memory leaks and become slow as molasses. Browsers routinely have exceptions during their execution: URLs are malformed or nonexistent, network connections evanesce, etc. These often result in memory leaks.

What is hard is managing the heap. valgrind is a great tool for this. Often poor exception handling leads to pools of undeallocated memory that pile up like cholesterol in the veins of your program.

The other thing that is difficult is that is possible to orphan still-needed items in memory. Try coding a singly-linked list from scratch in C without having memory leaks. It is an edifying and humility-instilling experience. Warning: valgrind will hurt your feelings.

$\endgroup$
  • $\begingroup$ Maybe it is exception handling that is hard then. To say nothing of cache invalidation and naming things. $\endgroup$ – Scott Rowe Aug 25 '18 at 23:19
  • 1
    $\begingroup$ Challenge accepted $\endgroup$ – Gypsy Spellweaver Aug 26 '18 at 2:32
  • 1
    $\begingroup$ Mission accomplished. Singly-linked list coded in C without memory leaks. Repo $\endgroup$ – Gypsy Spellweaver Aug 31 '18 at 18:09
  • $\begingroup$ That's an important coming-of-age achievement in the murky world of pointers and memory management. $\endgroup$ – ncmathsadist Sep 22 '18 at 15:18
2
$\begingroup$

As many others already wrote before, pointers by themselves are simple objects - in the C sense, not OOP - containing addresses of other objects.

If you start with C, you meet them very quickly, because they are immediatly required, together with dereferencing, for (emulating) passing parameters to actions "by reference". Exemple void swap_ints(int *ptr1, int *ptr2).

But "teaching pointers" is often a giant salad with too many ingredients

  • use of pointers as iterators over arrays while(*dst++ = *src++){}
  • dealing with dynamic allocation (and memory leaks/corruption problems)
  • linked data structures (insertion/deletion in lists, trees, etc).
  • pointer arithmetics,
  • ...

leading to a lot of confusions.

$\endgroup$
  • $\begingroup$ A "sword that turns every way" can be hard to handle. $\endgroup$ – Scott Rowe Aug 28 '18 at 17:15
  • $\begingroup$ Also Pascal courses were modeled after the Fortran initiation they replaced, so the "pointers" chapter that didn't exist in Fortran appeared after the usual chapters (themselves derived from the order of chapters in the first Fortran manual, another story). A reason to consider it as "advanced stuff" (and superfluous, like recursion) because nobody used that in the Fortran course. $\endgroup$ – Michel Billaud Aug 29 '18 at 13:41
  • $\begingroup$ Interesting, I have not given much thought to Fortran in a while. It was designed for handling mathematical problems, not for writing software. You probably could not write a compiler in Fortran (or SQL for that matter). There must be some sort of recognized distinction between "General Purpose" programming languages, and those designed for Domain Specific purposes. Excel can do a lot of stuff, but you can't write programs with it, despite it having several ways of handling indirection. Access is powerful, but reports are not really programs either. Sequence, Selection, Loop: choose any 3. $\endgroup$ – Scott Rowe Aug 29 '18 at 17:00
  • $\begingroup$ For exemple, the first Prolog interpreter was written in Fortran. $\endgroup$ – Michel Billaud Aug 30 '18 at 20:01
  • $\begingroup$ I wish I had more insight into the whole languages issue. Why were 400 High Level languages developed over the past 30 years or so? I am told that some are optimized for some purposes. But the SICP book showed 35 years ago that one can create essentially anything at all pretty easily with Lisp. The fault is apparently not in our CPUs, but in ourselves. $\endgroup$ – Scott Rowe Aug 31 '18 at 13:12
1
$\begingroup$

I agree with @Buffy but would like to add, that I don't think that the lack of garbage collection is the only problem.

In C a variable can be a concrete variable, a pointer, a pointer to a pointer, … Where as in Java everything is a reference (except where it is not (basic types) ug). This can make it very confusing as to what type this variable is.

I have found that a little bit of Hungarian-notation can help (but not to much). It may however be better to just avoid, until the student is at least a competent programmer.

e.g.

int height;
int *height_pt;
int **height_pt_pt; /*if you need such a thing*/
$\endgroup$
  • 1
    $\begingroup$ C is a polite veneer over Assembly. C programmers know that a memory location holds a binary number, but that number could represent a constant, the location of a variable, a pointer - which might change as the program runs, and so on. C programmers have to know how the machine really works, so they are not confused or mislead that there are different kinds of things in memory. No, there are just bits in memory. The compiler helps you organize that, but it is up to the programmer to know what they mean by each type of thing. Like how all living things have DNA as their representation. $\endgroup$ – Scott Rowe Aug 24 '18 at 14:33
  • $\begingroup$ @ScottRowe you sound like von neumann. He thought that assemblers were for week minded people. I am (have been) a C programmer. I choose names that help me. computers have good memory, I don't. If you think other-wise, then just name your variables a, b, c, d, e, etc. $\endgroup$ – ctrl-alt-delor Aug 26 '18 at 16:40
  • $\begingroup$ No sweat, I am a C programmer too. All I am saying, is that students need to know what is under the hood (bonnet) so to speak. They don't need to have their hands greasy all the time. I can solder, but lightswitches are great. $\endgroup$ – Scott Rowe Aug 27 '18 at 15:04
  • $\begingroup$ At the time of Von Neumann, these young female math students assembling programs by hand were much cheaper than computer time. Although more error prone, which happened to waste this precious computer time too, so he changed his mind afterall. $\endgroup$ – Michel Billaud Aug 29 '18 at 13:37
1
$\begingroup$

The basic idea of pointers is simple, but here are two examples that illustrate why they are tricky, even in a language like Java that handles memory management for you.

  1. A function takes a list as input, called inList. That function modifies the list. The list that was passed to that function with a different variable name is ALSO modified because both variables point to the same list in memory. Yet if we pass an integer in Java to a function, the function cannot change the variable that was passed to it because it's not a reference. This is distinction trips up some of my students.
    1. I was working on a reasonably large professional project that handled exam scheduling with Student and Teacher objects. References to teachers and exams were getting lost. Data was getting lost and it took me a while to realize why. Sometimes when the user edited an object, a new object was created, but the master list was still referencing the old object. Without understanding references I couldn't not have fixed this critical bug.
$\endgroup$
1
$\begingroup$

In a nutshell, we can say that though pointers appear to be a simple idea to understand their basic functionality, the difficulty arises due to the many associated concepts of pointer management and utilization. These are referencing, dereferencing, allocation, deallocation, sequential indexing, parameter passing (call by value!), pointers to pointers, typecasting, self references in objects, dynamic binding etc., which need to be understood to know how pointers can be used correctly and efficiently. To address a part of the difficulty of pointer management, we have the auto_ptr template class in the c++ STL.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.