Live data from Hacker News

Ask HN: Favorite pointer tricks in C?

news.ycombinator.com

31–40 of 81 posts

Re: Ask HN: Favorite pointer tricks in C?

#31
post #9

One that comes to mind: struct name { int namelen; char namestr[1]; }; struct name *makename(char *newname) { struct name *ret = malloc(sizeof(struct name)-1 + strlen(newname)+1); /* -1 for initial [1]; +1 for \0 */ if(ret != NULL) { ret->namelen = strlen(newname); strcpy(ret->namestr, newname); } return ret; } (From http://c-faq.com/struct/structhack.html ) Simple way of storing a string's name and length in one all…

The correct way to write this is to not use /1/ in the size of namestr, it's to use a simple []. This tells subsequent programmers that you are using variable length structures. In older compilers, the metaphor was to use '0', but C99 (maybe even earlier) got everyone using [].

Here's a nice discussion in StackOverflow, including a bunch of C++ guys saying to just use Vectors, which ignores the entire point of getting a structure with only one memory allocation:

http://stackoverflow.com/questions/688471/variable-sized-str...

Re: Ask HN: Favorite pointer tricks in C?

#32
post #5

What I think takes the cake is this: array[index] == index[array] Not that you would actually use this, but it gave me a lot of insight into how addressing and stuff works inside the compiler. Also from this example, there's the implicit suggestion that an array can be treated as a pointer. So that leads into pointer arithmetic which can be very useful.

The same as above, only using Pointer Arithmetic instead of Array Subscripting:

    *(array + index) == *(index + array)
Further broken down:

    *(&array[0] + index) == *(index + &array[0])

Re: Ask HN: Favorite pointer tricks in C?

#33
post #12

You can demonstrate pointer arithmetic by showing how you would work with the strstr function. It's the clearest and most understandable reason for someone to see why you'd even discuss this topic I think. I talk to some people without C experience and they hear that idea and get scared. I usually explain how strstr works and that seems to always make sense to them. Good luck!

char buf[1024]; /* should be enough */ I actually write this a lot in my code. Not code that I intend to share with others, of course. But I do find it amusing about the value I put in brackets. I find it amusing that I have an OCD-like predisposition to make it a power of two. And I find it amusing how the number between the brackets has increased over the last ten years, from a frugal 64 to an opulent 1024. This, t…

This avoids allocation and is safe (the cost of two extra compares is low because they'll branch the same way all the time, so you'll get branch prediction power)

  char *bufp;
  uint8_t buf[1024];
  if (need_sz >= 1024)
    bufp = malloc(need_sz);
  else
    bufp = buf;
  ....
  if (bufp != buf) free(bufp);

Re: Ask HN: Favorite pointer tricks in C?

#34
post #5

What I think takes the cake is this: array[index] == index[array] Not that you would actually use this, but it gave me a lot of insight into how addressing and stuff works inside the compiler. Also from this example, there's the implicit suggestion that an array can be treated as a pointer. So that leads into pointer arithmetic which can be very useful.

You didn't really spell out why this trick works:

    array[index] == *(array + index) == *(index + array) == index[array]

Re: Ask HN: Favorite pointer tricks in C?

#36
post #25

* Using pointer offsets to get to the stack frame pointer, and then walking the frame pointer backwards to get the call stack. * Using && to take the address of a jump label. * Casting a u_int32_t over a 4-byte string (like an SMTP verb) to get a value you can switch() on.

> Casting a u_int32_t over a 4-byte string (like an SMTP verb) to get a value you can switch() on.

This is awesome beyond words. If I stumbled across this in the wild I would flip flop between awe and disgust until my head exploded.

Let me guess, "SMTP verb" is not a hypothetical example?

Re: Ask HN: Favorite pointer tricks in C?

#37
Instead of using a while loop to iterate through a linked list, consider using a for loop.

  Node * iter;
  for (iter=root; iter != NULL; iter=iter->next) {
       /* iter->object; */
  }
A concise implementation of strlen

  size_t strlen(char * str) {
     char * cur;
     for(cur=str; *cur; ++cur);
     return (cur-str);
  }
Reverse a string in-place.

  void reverse(char * str) {
    char *i,*j, tmp;
    for (i=str, j=(str+strlen(str)-1); i 

Re: Ask HN: Favorite pointer tricks in C?

#38
post #5

What I think takes the cake is this: array[index] == index[array] Not that you would actually use this, but it gave me a lot of insight into how addressing and stuff works inside the compiler. Also from this example, there's the implicit suggestion that an array can be treated as a pointer. So that leads into pointer arithmetic which can be very useful.

The same as above, only using Pointer Arithmetic instead of Array Subscripting: *(array + index) == *(index + array) Further broken down: *(&array[0] + index) == *(index + &array[0])

Yep. And if teaching that to a bunch of middle or high schoolers, I would add that pointer arith works in increments of sizeof(array[0]) bytes. If you're not careful about operator precedence in moderately complicated expressions, that could come back to bite you.

Re: Ask HN: Favorite pointer tricks in C?

#39
My favorite pointer trick is a simple one. I learned it when I had to implement it (in 64-bit) in a C compiler.

Simply, you can subtract pointers. Let's say you're walking a string from the front and from the back at the same time, and want to find the length of the substring. Well, you don't have to use indeces, just do this:

   int len = back_ptr - front_ptr;
You'd be surprised how often this crops up when you're using lots of pointer tricks.

Re: Ask HN: Favorite pointer tricks in C?

#40

Instead of using a while loop to iterate through a linked list, consider using a for loop. Node * iter; for (iter=root; iter != NULL; iter=iter->next) { /* iter->object; */ } A concise implementation of strlen size_t strlen(char * str) { char * cur; for(cur=str; *cur; ++cur); return (cur-str); } Reverse a string in-place. void reverse(char * str) { char *i,*j, tmp; for (i=str, j=(str+strlen(str)-1); i

You have a bug in strlen:

     for(cur=str; cur; ++cur);
should be:

     for(cur=str; *cur; ++cur);
Post reply on HN