neil: as for fixed-sized buffers:
char *buf = NULL;
size_t len = 0;
int c;

while( (c = getchar()) != EOF ) { 
   buf = realloc( buf, ++len );
   buf[len-1] = c;
}
buf = realloc( buf, len+1 );
buf[len] = 0;
No loss. That's what realloc is there for. Just don't forget to free().

Speaking of realloc, one that's tricky is stale pointers with that. You realloc something, you have to re-assign each pointer to it; this can be difficult in a threaded program.

NULL pointer stuff is pretty obvious, so I won't go into that. There's also the problem of never assigning a value to a pointer, then trying to dereference it. That's pretty easy to track and fix once you find it though. There's also accidentally casting an int or some such into a pointer (ouch!), but again, that's pretty easy to track. I'd say it's definitely forgetting to free(). The rest can be fixed with a good debugger.