Want to read Slashdot from your mobile device? Point it at m.slashdot.org and keep reading!

 



Forgot your password?
typodupeerror
User Journal

Journal ryanr's Journal: Bug Puzzle #3 15

Quick one this time.

typedef struct _BUF
{
    int size;
    char buf[1024];
} BUF;

int main ()
{
    BUF *buf;
    buf = (BUF *)malloc (sizeof (BUF));
    memset (&buf, 0, sizeof (buf));
    buf->size = 10;
    return 0;
}

# gcc bug3.c
# ./a.out
Segmentation fault (core dumped)

If you're paying attention, you'll find 2 bugs there.

This discussion has been archived. No new comments can be posted.

Bug Puzzle #3

Comments Filter:
  • Here's one answer. The memset call is set to overwrite the value of the pointer, resetting buf to point to 0. Then, dereferencing it yields a core dump.

    But I'm not paying enough attention to see the second bug.
    • You got the main one (which causes the segfault). Since memset takes a void pointer, the compiler can't help you with the fact that I've used the wrong level of indirection here. The fix is to pass the ptr, not the address of the pointer (remove the &). As you've pointed out, the way I have it now, it overwrites the pointer contents (which was the address of the buffer malloc just returned), plus whatever else comes after, up to the sizeof (BUF).

      The second bug is a bit more subtle, and won't neccess
  • Comment removed based on user account deletion
    • Doesn't this line overwrite the entire buf struct, and not the buf in the struct?

      That was the intention. My choice of having a member named buf in a structure named buf was probably poor for example purposes. :)

      But the line as I wrote it doesn't work as intended.

      re: 0 vs. '\0'... in C, a char is exactly the same as a short int. To the point that I've never seen a C compiler complain about it. You might call it a style bug. :)
  • Umm, doode, Buffy is much smaller than a size 10.
  • blah blah blah, schmuelp already got it, blah blah blah,

    but these are damn cool. keep up the good work.

    P.S.- what is the advantage to using memset as opposed to just for looping it yourself using pointer arithmetic (int pointer despite it being a struct)? Is it just that its bad form to violate types like that?

    • Not "bad" per se. memset, memcpy, etc... will often bit a bit more efficient. The usually move things about in register-size chunks. For example, on x86, they will move things (or set them to 0) 4 bytes at a time, and then finally a word, and then a byte if it's not an even multiple of 4.

      I should probably just be using calloc, which I didn't know about until recently. I picked up the malloc (sizeof()); memset (or bzero, where supported) from reading other people's code. I don't know why calloc isn't u
      • Yeah, I mentioned calloc in a code inspection and no one knew what I was talking about. Maybe its an application space routine, only?

        As for register sized chunks, you can do that on your own, however if you are trying to write platform independent code... let the libraries do it for you!
  • These bugs are some cool stuff. I haven't used my C in a long time, and now that I'm getting back into it these are actually useful. Debugging pointers is a pain so this is good practice. Keep it up!
  • 1. you shouldn't pass the address of *buf to memset, as it's already a pointer.

    2. In the same line, you want the sizeof(BUF), not the sizeof(buf). The first gives you the size of the struct, the second, the size of the pointer.

"Can you program?" "Well, I'm literate, if that's what you mean!"

Working...