• Dani (unregistered)

    Excellent stuff! If you can't put some humor in coding then where can you?

  • Ray S (unregistered)

    Hey, at least the kid had the excuse of being a student. Some of us have to deal with this crap in the real world with alleged 'professionals'.

    That said, I do love the name, and if "-18 for sucking at life" is true, extra points for hilarity. :-)

  • James Mastros (unregistered)

    Ugh. You know, if either of you had been that kid, you would have escilated that, and the prof, or some other higher-up, would have been forced to do something, and the kid would likely have been given a higher grade which they did not deserve.
    <ul>
    <li>-4 for poor name.</li>
    <li>-4 for unneccessary cast</li>
    <li>-6 for dereferencing a freed pointer</li>
    <li>-6 for not having an exit condition</li>
    </ul>

    Same grade, but penilizing people for "sucking at life" is simply not a valid thing to do.

  • Daniel R (unregistered)

    And what about penalizing him for dereferencing a void pointer? I think the "significant names for variables and functions" is a bit subjective but compiler and error warning are worse than a funny name.

  • l33t h4x0r (unregistered)

    Note: It is perfectly legal to call free() with a null-pointer. It simply does nothing.

    Now our score improved to -19.

    But you should never use a pointer after freeing it. Back at -20.

    ;-)

  • Meh. (unregistered)

    > Same grade, but penilizing people for "sucking at life" is simply not a valid thing to do.

    Although I agree with the wording, I would have cut the poor name and unnecessary cast demerits in half, and then added "-4 for turning in obviously broken code that you haven't tested, wasting my time."

    (Sometimes, btw, a cast that may be unneccessary is in fact there sometimes to explicitly force a certain type promotion, or make an implicit promotion explicit. This is especially true when working with third-party libraries; if you find yourself doing this with your own code, overload your function for the original type if it is suitably meaningful.)

  • Arf arf arf (unregistered)

    Mr. Mastros, my impression is that the student so penile to begin with that no TA could've made him any more so.

    l33t h4x0r d00d: The problem is that he'll end up dereferencing NULL when he recurses -- or at least he will be if he set tail->next to NULL when he built the list. Anybody here trust him to have gotten that right? Yeah, me neither... In that case, at the end of the list he'll follow a gibberish pointer to Podunk and end up with an access violation. Unless he accidentally used calloc() instead of malloc().

    I did once work with somebody who thought that the C++ delete operator set the pointer to NULL. So he'd always say

    if ( p ) delete p;

    ...and then do it again for the same p later on. He ultimately decided that operator delete "wasn't working right"; it was "just corrupting the object instead of deleting it".

  • Tom Seddon (unregistered)

    Any pointer turns into void *. That's why the cast is wrong -- it's unnecessary, and it stops the compiler error if you accidentally pass the wrong type of variable (due to a typo, say).

  • TheF0o1 (unregistered)

    > ... you would have escilated that...
    > <li>-4 for unneccessary cast</li>
    > ... but penilizing people for "sucking at life" is simply not a valid thing to do.

    -3 for misspelling "escalated", "unnecessary", and "penalizing"
    -3 for poor grammar
    No penalty for sucking at life

  • Justin Lovell (unregistered)

    I do not know why some people are surprised at stupid names? When it comes down to code that will be looked at only once and is not a "critical" piece of code for my classes, I have some stuff like this:

    program SomeStupidTestThatWasDecidedToBeWrittenOneDayBeforeHolidays;

    begin
    writeln('You are a stupid user! And because I am the most intelligent piece of code, I can predict that you want to exit out this programme right now... press any key to exit.');
    readkey;

    writeln('Fooled yea! The stupid piece of code will be executed momentarily...');
    delay(10000);


    {... actual code ...}
    end.

    Jeez! This is what I do for fun just BECAUSE I have to code in Pascal for school.

  • Ron (unregistered)

    Ha hah ahaha

    Obviously none of you guys went to CMU.

    At CMU it is perfectly valid to tell someone they suck at life. Although it should be a given, since you are an undergrad at CMU.


  • josh (unregistered)

    The problem is not checking for NULL before freeing the pointer, the problem is not checking for NULL as an exit condition. Even dereferencing NULL is a secondary problem. Since this code is dereferencing the pointer only after it is freed anyway, the value it held is ultimately irrelevant at that point.

  • Andy (unregistered)

    When I was in college we had a Scheme professor (he also taught a C++ class the following semester) who could barely speak English and was a mediocre teacher in general. One of my friends took to turning in all his assignments with every variable, function, etc. named "thingy" or a variation on the word or a profanity.

    Got at least a B in both classes, probably a B+ or A (been a few years).

  • Jeff Perrin (unregistered)

    Heh. You said "penilizing"

  • Tiernan O'Toole (unregistered)

    i was that kid, well not in the example, but in my class. i was docked 15% in a programming exam, of which i got 85% BTW, for not having a button other then the standard windows one, for killing the program. there was a menu, there was the windows one, the program did everything it was ment to do on the spec, but the ba****d docked me 15% for not having a button. still pi**ed of to this day because of it. still got an A but thats not the point.

  • James (unregistered)

    We actually had someone at Uni submit his haskell code with functions along the lines of "HaskellIsCrap", "B*****dHaskell" and so forth.
    He even got reasonable marks, considering that half the functions didn't work that is.

    But then even I managed to get some RIP acronyms into my Prolog.

  • KoFFiE (unregistered)

    > QUOTE:
    > Note: It is perfectly legal to call free() with a null-pointer. It simply does nothing.

    As stated above - he should have checked it and exited, and also - lucky you that you only code on PC-platform :) I code on embedded (mostly m68k) systems, and calling "free(0);" on some platforms is a quick (and dirty?) trick for an instant reboot... I know - not really standard C, but good practice to avoid such things from happening imho, and if you know this, this can be real handy, the resetting of a system is most of the time some obscure system call. free(0) is a LOT easier :D

    Disclaimer: the free(0) trick is only used in debug versions of these platforms supporting this "feature" to indicate something really really bad went wrong :)

    Also another remark, this implementation is pritty stack-intensive (at least if working with a stack-oriented platform/compiler, but since most are...), even if the logic itself would be ok hence it's recursive behavior. I still wouldn't use it to free a linked list of 10.000 items :) Offcourse some compilers optimize this into a loop, but I don't like that that much :)

  • Distilled Software Hate (unregistered)

    On some UNIX systems they used to set the word at zero to zero so indirecting through an extra null pointer was mostly safe. For all I know some platforms (SCO, maybe) still do this. On those platforms he'll get a segfault or bus error when he blows the stack instead of when he follows the null pointer to madness or blows out on a protection fault.

    He's also depending on malloc allowing one use-after-free. With a debugging malloc or a secure free he'd hit a wild pointer or a null poiinter right off no matter what the list is.

  • defrost (unregistered)

    Just for the record;

    free( head ); // does NOT make head==NULL
    and so
    FreeThisSchnizzle( head->next );
    will NOT dereference a NULL ptr, it will pass
    the value at offset of member next after the pointer head, which still retains it's previous pointer value.

    What actually happens is implementation dependant, behaviour will range from "works as expected" to a segfault / bus error ...

  • Jon Hanna (unregistered)

    > free( head ); // does NOT make head==NULL

    No, but recursing through a linked list with the end node marked by having a null next pointer does (eventually, after you call FreeThisSchnizzle() on that null next pointer).

    >What actually happens is implementation dependant,

    No, it is undefined. Were it implementation dependant then any given implementation would have to document its behaviour (which may be completely up to the implementation, or one of a few possible options).

    As both derefencing a null pointer and dereferencing a pointer to an object that has been freed are undefined a compiler can do whatever it wants, and this can change between releases of the compiler without any warning. It can also change depending on debug options (and they often do, as debuggers will try to catch just the two errors above, assuming the compiler didn't already catch the fact that the function never returns).

    Relying on implementation dependant behaviour is generally a Bad Thing but ocassionally necesary (in particular in very low-level code). Relying on undefined behaviour is just wrong. As a coder (rather than a compiler developer) it's best to read "undefined" in the standard as "Breaks. Horribly."

    >behaviour will range from "works as expected" to

    It is recursion without a condition that will stop the condition.

    It might just be (not sure) theoretically possible for a compliant compiler to:

    1. Not break at the use of a feed pointer.
    2. Not break at the dereferencing of a null pointer.
    3. Optimise the tail-recursion into an iteration, so there is no stack overflow[].
    4. Realise that the iteration is no longer doing anything after it has reached the null pointer and optimise it away, to a more efficient behaviour that is the same "as if" it hadn't optimised; i.e. putting the thread to sleep (but not killing it, unless there was no references to the thread's handle stored)
    5. Making the thread permanently sleep isn't a disaster for the rest of the program.

    The success of this would be just slightly less dependent on luck than if you gave the same assignment to a blind monkey with carpal tunnel syndrome.

    [
    ] The only thing that indicates any method in the madness in FreeThisSchnizzle is that while the recursive call clearly should be before the call to free it may have been put at the end in the hope of making the recursion tail recursion and hence allowing the compiler to quite easily make it an iteration.

  • Slom (unregistered)

    Jon Hanna : "As both derefencing a null pointer and dereferencing a pointer to an object that has been freed are undefined"

    dereferencing NULL is perfectly valid and defined ansi-c !
    ( avoiding if(x) free (x) constructs, simply results in a NOP)

  • Slom (unregistered)

    meant freeing
    SRY

  • nick (unregistered)

    >> free( head ); // does NOT make head==NULL

    >No, but recursing through a linked list with the end node marked by having a null next pointer does (eventually, after you call FreeThisSchnizzle() on that null next pointer).

    Point is that it won't (legally) recurse -- the damage (de-referencing an already freed pointer) is done on the first iteration so the NULL at the end is technically irrelevant

  • Chui Tey (unregistered)

    I'm surprised no one pointed out that the recursion doesn't terminate (until you run out of stack space, that is).

  • Ian (unregistered)

    Haha... that was me.


    The TA, not the student. :P

  • Ian (unregistered)

    And looking back... Levi sent in the wrong code there. The exact code from my records was such:

    void freeThisShnizzle(Word *node)
    {
    if (node!=NULL)
    freeThisShnizzle( node );
    free(node);
    }

    Note that our recursive call is before our call to free... additionally nothing is ever set to null. I rapidly ran out of stack space when running this student's code, and then when I saw why...well... I thought he deserved a more specific penalty than a flat -20.

  • (unregistered)

    Somebody, just sent me this link. I am the person who wrote this code. Apparantly people still talk about this. Some guy came up to me in graphics last semester talking about it, and nearly wanted my autograph when I told him. I've still got a video of the class in which everyone laughed at me if anyone wants it [:D]. The code listed a few posts up is what I turned in, not the one in the first post, and the first -1 was for turning in an infinitely recursive function.

    In my defense, this class isn't very serious, as its just a half semester intro to c, and for christ's sake, the labs were due on friday night!

  • (unregistered) in reply to

    Actually, I made a mistake. The -18 was for the infinite recursion, and the -1 was for sucking at life.

  • (unregistered) in reply to

    Sorry for the spam, but here's the video http://www.andrew.cmu.edu/user/rmoulton/FreeThisShnizzle.wmv

  • (cs)
    Alex Papadimoulis:
    • -1 for not checking if the pointer is null and for calling free() before recursing.
    • -1 for calling this function FreeThisSchnizzle()
    • -18 for sucking at life

    What about "using recursion when iteration will do the job"?

  • (cs) in reply to Ian

    :
    And looking back... Levi sent in the wrong code there. The exact code from my records was such:

    Ok, let's reflect on this a moment.  A person, in attempting to offer some code to TheDailyWTF,

        (a) inadvertantly fixes the one error in the code, but

        (b) injects three NEW errors into it!

     

    Now, that's a WTF!

     

  • (cs)

    The original code would have caused this statistic in one of our programming classes:

    • Starting points: 100
    • Does not compile: -100
    • End result: 0
  • (unregistered)

    Can I tell you all a joke I read on the internet?

    Okay...here goes.

    Why was Snoop Doggy Dogg carrying an umbrella?

    Fo' Drizzle.

  • (unregistered) in reply to
    In your defense?  But it doesn't compile!  Even if it was due on a Friday night (was it assigned Friday morning?), can't you at least try to compile and run the thing? 
     
    Why take a half-semester "intro to C class" in the first place if you don't care to learn C?
     
    Sheesh.
     
    David W.
  • (unregistered) in reply to
    That was intended for Anonymous, who said a few posts back "In my defense....."
     
    David W
  • (unregistered)

    Didn't anyone find the Snoop Dogg joke funny? I did.

    That sort of "speak" makes me laugh.

    Everytime I hear someone say something like "Fo' heezy" or "That's the sheezy." I have to say "Bless you." because it sounds like they sneezed.

  • (unregistered) in reply to

    I don't think that joke is funny because I don't speak that language.  I never heard those expressions before.

    Please translate them into English.

  • (unregistered) in reply to

    :
    I don't think that joke is funny because I don't speak that language.  I never heard those expressions before.

    Please translate them into English.

    Y'know, I would love to translate them for you, however I myself don't know what they mean.

    I just think they sound funny.

  • (unregistered)

    A-skizzle! A-skizzle!

    Excuse me...

    I had to sneeze. [:^)]

  • (unregistered)

    You're excuzzed.

  • Matt (unregistered)

    So I was actually in this class, and the best part was when the TA put the code up on the monitor:

     

    "Ok everyone, what's the problem with this code?"

    "uhh . . it's an infinite loop that will overflow the stack space?"

    "No! The problem is that it's named FreeThisSchnizzle!"

  • (cs) in reply to Chui Tey
    Anonymous:
    I'm surprised no one pointed out that the recursion doesn't terminate (until you run out of stack space, that is).


    And possibly not even then, if (for example) it were compiled with gcc 3.* using the -foptimize-sibling-calls switch (or -O2, which includes that one). That makes it one of the few valid arguments against TCO I've seen.
  • Suomynona (unregistered) in reply to Jon Hanna
    Anonymous:

    No, it is *undefined*. Were it implementation dependant then any given implementation would have to document its behaviour (which may be completely up to the implementation, or one of a few possible options).


    You're confusing "implementation dependant" with "implementation-defined", which is standardese for what you describe. Argument from authority: I know what I'm talking about, because I had to read the C99 standard for money. ;-p

  • Suomynona (unregistered) in reply to Slom
    Anonymous:

    dereferencing NULL is perfectly valid and defined ansi-c !
    ( avoiding if(x) free (x) constructs, simply results in a NOP)


    You meant freeing NULL is valid ANSI-C, but actually, dereferencing NULL is also valid ANSI-C. Only if you do anything useful with the dereferenced pointer is the behavior undefined.

    For example, C99 explicitely states that &*p for a pointer p is equivalent to p, even if p == NULL.

  • (cs) in reply to
    Anonymous:


    In my defense, this class isn't very serious, as its just a half semester intro to c, and for christ's sake, the labs were due on friday night!



    This is the only valid WTF justification I have seen on these boards so far!
  • (cs) in reply to Suomynona

    Anonymous:
    I know what I'm talking about, because I had to read the C99 standard for money. ;-p
    ah... but did you find the limerick?

     

     

    (OK, it's actually in the C++98 standard)

  • David Schwartz (unregistered)

    I once worked on a project that had so much code like this, they simply changed the "free" function so that it free's whatever you passed it on the previous call to "free" and saves this pointer to free NEXT time.

    I couldn't understand how they could ever get to this point. All the ways I could imagine this happening had "checking and egg" issues. Why write the "delayed free" if you didn't have code like this? And why write code like this if you had a "delayed" free?

    I finally tracked down the history. They once had a bug just like this, and as a quick workaround (it wasn't as trivial a fix as this example) they wrote the "delayed free" function. The problem was solved, so why mess with it? Over time, more bugs crept in that weren't detected because "delayed free" hid them, so over time, they just started writing to the "delayed free" model.

    YUCK.

  • Alex Gartrell (unregistered)

    Can't we keep this kind of stuff in-house?

  • Regular Person (unregistered)

    Great Post!

    This kid sounds like such a douche! He tried to implement HUMOR into an entry level computer programming class?

    We all know programmers (as a group) tend to be taken very seriously, so this type of behavior only makes us look uncool.

    .......

    .....

    ...

  • radaway (unregistered) in reply to l33t h4x0r

    Yeah but you supposedly want to stop the recursion eventually.

Leave a comment on “FreeThisSchnizzle()”

Log In or post as a guest

Replying to comment #:

« Return to Article