C Pointer Problems
This was written in January of 1990, but is still meaningful
today, though we do have better debugging tools now. This
was originally published in the Boston Computer Society's PC Report.
I admit it: I'm sometimes just not careful where I'm pointing. In
ordinary life, careless pointing might be rude, but in C programming, it
tends to be unforgivable.
Right now, for example, I'm chasing an errant pointer that cannot be
found using Codeview (Microsoft's debugger). That is, if run under
Codeview, the program works correctly, but crashes when run without it.
This might sound like a real hair-tearer, but usually this kind of
problem isn't too hard to find. Usually, that is.
If a program works under a debugger but crashes otherwise, the
problem is almost always an uninitialized pointer. The reason it
works during debugging is because the debugger either provides
initialization or happens to arrange memory so that your error doesn't
hurt anything important. Every time this happens, it turns out that
I've screwed up. Every time. All I have to do is find where I
made the mistake.
This particular pointer is hiding very well. So well that it actually
is hard to crash it on my machine: I have to feed it garbage data to
see the problem. On my client's hardware, it pops up without provocation,
and destroys screens, rampaging through data in memory, changing this and
discarding that, and ultimately exits with the dreaded "Null Pointer
Assignment" message. Sometimes. Other times, the program just clicks
along, doing its thing. Frustratingly random, so very hard to find.
It is tempting (so very tempting) to blame this on hardware. We are
talking about an off-brand machine, and a 386SX at that. "Works OK here",
wash my hands and walk away. Trouble is, everything else in the world
works fine on that box. Every diagnostic gives this machine a totally
clean bill of health. And there is that nagging reality that, albeit with
difficulty, I can cause the problem on my own machine. The error may be
esoteric, but it is real.
My first approach is calm and logical. I wrote the code, I understand
its intent, I am a supposedly intelligent person - I can find this by carefully
reading the source.
That lunacy lasts about ten minutes. There is no way I'm going to read 107K
of source code. In fact, I'm banging away at the keyboard before I'm
two screens into the first source file. Banging what? Why "printf"'s, of
course. Dozens of "The address of Dir_now is %p and the contents are %s\n"
thing-a-mungies are now cluttering the code. Remember Codeview is no help
because it works under Codeview. And DEBUG is no help because DEBUG is no help.
Days later I was back to the scientific approach. The printf's hadn't helped, and I was getting slap happy. I had visions of Kernighan and Ritchie
using excerpts of my code for a new book: "Making an unbelievable mess with C, a Case Study". I started adding sarcastic comments to my code:
/* Real smart using floats for "for next loops" */
/* Gee, do any of these variable names MEAN anything? */
I also started adding apologies:
/* Added this at 2:00 AM - need to fix */
/* Really rushed here - I can fix this later */
/* There's a reason for this mess here - honest */
Bald faced lies, of course, added only in case I had to enlist someone
else to help me find this thing.
The Zen approach seemed worth a try. You know, you just inform your
subconscious that this problem is serious, and then you go off
and do something else. Within a few days, the solution will magically
appear, perhaps in a dream. My subconcious had to be aware of how distressed
I was - would I absent mindedly pop a handful of our pet gerbil's food
pellets in my mouth were I not stressed? So I decided to do something
else for a day or two. No luck: my subconscious has apparently moved to
Cincinatti; I haven't heard anything from it in weeks.
Yesterday I gave a copy of my code to a friend in hopes he can spot
the problem. I'm getting desperate here..
My friend called, opening with caustic comments about aesthetics and user
friendliness, peppered with snide observations on sloppy coding. "But
does it crash on your box?", I asked. "No, it doesn't, unless I feed it
your 'bad' data. You have an uninitialized pointer." Hopefully I asked,
"Do you know where?". He laughed. "You know what you have to do, right?"
Yes, unfortunately I do. Back to the "printf"'s.
If this page was useful to you, please help others find it:
More Articles by Tony Lawrence
- Find me on Google+
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more. We appreciate comments and article submissions.
Jump to Comments
Many of the products and books I review are things I purchased for my own use. Some were given to me specifically for the purpose of reviewing them. I resell or can earn commissions from the sale of some of these items. Links within these pages may be affiliate links that pay me for referring you to them. That's mostly insignificant amounts of money; whenever it is not I have made my relationship plain. I also may own stock in companies mentioned here. If you have any question, please do feel free to contact me.
Specific links that take you to pages that allow you to purchase the item I reviewed are very likely to pay me a commission. Many of the books I review were given to me by the publishers specifically for the purpose of writing a review. These gifts and referral fees do not affect my opinions; I often give bad reviews anyway.
We use Google third-party advertising companies to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, click here.