Getting to the point(ers) about COf all the features of the C language that are the easiest to use – or at least, without the problems faced when using such unruly features as volatile keywords and malloc - is the pointer data type.
It is used to reference a value directly to (or "point to") another value stored elsewhere in the computer memory using its address Its main function is for constructing references, which are fundamental to constructing nearly all data structures, as well as in passing data between different parts of a program.
Not that it is without its own unique set of problems. Though simple in concept (or because of it) pointers are used extensively in C (and C++) programming in a variety of ways. And because of that ubiquity, this can lead to a variety of problems that only careful attention to their use can prevent.
This issue of the Tech Focus Newsletter contains a variety of design articles and columns that on this topic ranging from the basics of pointers to its more complex uses, and the types of problems that may be encountered.
Their use is absolutely necessary in most 8- and 16-bit MCU designs. And the shift to 32-bit MCUs will only exacerbate the problems as code sizes get larger and applications become more complex.
Pointers effectively take the place of general purpose registers and in microcontroller designs go a long way in improving performance for repetitive operations such as traversing strings, lookup tables, control tables and tree structures.
It is much easier for the programmer to copy and dereference pointers than it is to copy and access the data to which the pointers point. Pointers are also used to hold the addresses of entry points for called subroutines and for run-time linking to dynamic link libraries (DLLs).
When the task at hand is to setup and manage lists, queues and trees, the use of start, end and stack pointers are helpful in managing how data structures are implemented and controlled. When creating control tables to manage and direct program flow, pointers are usually incorporated into a table entry and used to hold the entry points to subroutines to be executed.
They can also be used to index to other separate, but associated, tables each containing an array of the actual addresses or the addresses themselves. They’re also used to point (back) to earlier table entries (as in loop processing) or forward to skip some table entries.
Pointers can also be used to allocate and deallocate dynamic variables and arrays in memory. In tightly constrained MCU designs, such variables are wasteful of memory after they have served their purpose. So it is usually necessary to deallocate them when no longer needed. Failure to do so often results in memory leaks, disastrous in many MCU operations.
The usefulness of pointers is so great that it’s difficult to think of a programming task in C that could be performed without them. And that very usefulness in a variety of tasks makes pointers a source of a variety of programming errors, in addition to memory leakage.
For one thing as long as they can be directly manipulated as a number, they can be made to point to unused addresses or to data which is being used for other purposes, with all the possibilities for errors that implies. Then there are wild pointers and dangling pointers.
The first is a pointer which does not have any address assigned to it and if used can cause unexpected behaviors, sometimes because the initial value is not a valid address, or maybe cause damage to other parts of the program in which it is used.
In the second case, dangling pointers deallocate the memory region they point to. If that memory region contains the same data as it did before it was deallocated but is then reallocated and overwritten by unrelated code, the programmer is up a creek without a paddle and really does not know what will happen.
Some of the articles and blogs in this week’s Tech Focus newsletter will be good starting points to learning - or relearning – the basics about pointers and their many uses, and misuses. Others, such as several contributions by Dan Saks, provide considerable insight and guidance in some of the complex issues that pointers present to programmers.
One that I found very informative was “Computing properly aligned pointer values” in which Dan provides details on how to avoid the undefined behavior that arises when using array allocation and deallocation functions in C on a machine with strictly aligned types. Other Dan Saks columns on my Editor’s Top Picks list are:
One of my all-time favorite articles (though Dan may disapprove) remains Mengjin Su’s somewhat contrarian article on “Saving space with Pointer-less C,” in which the author describes a new grammar for replacing the pointer operations in C. The proposed grammar eliminated the declaration of all kinds of pointers, as well as their operations. Instead, it uses normal integer variables as the "holders" that denote the memory location to be accessed.
The approach taken by the author remains controversial, least of all with Dan Saks, who at the time thought it should not have been published on Embedded.com. But as contrarian as it was, I found the article enormously useful as a backwards sort of way to understand how this feature can be applied, and the problems faced by developers.
Embedded.com Site Editor Bernard Cole is also editor of the twice-a-week Embedded.com newsletters as well as a partner in the TechRite Associates editorial services consultancy. He welcomes your feedback. Send an email to firstname.lastname@example.org, or call 928-525-9087.