Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

[CodeCritique] Criticize my Linked List

Name: Anonymous 2011-08-19 20:33

I have implemented linked lists in C as a learning exercise.  I'm a noob ass so tell me how my implementation sucks and I will fix it.  I didn't have a particular use-case in mind when I wrote it.

Header:
// llist.h
#ifndef LLIST_H_
#define LLIST_H_

struct LList;
typedef struct LList LList;

struct LLNode;
typedef struct LLNode LLNode;

struct LList {
    LLNode *front, *back;
};

struct LLNode {
    void *data;
    LLNode *next;
};

LList* llist_new(LList **self);
void llist_add(LList *self, void *v);
void llist_remove(LList *self, LLNode *node);
void llist_insert(LLNode *node, void *v);
void llist_destroy(LList *self);

#endif


C file:
// llist.c
#include <assert.h>
#include <stdlib.h>

#include "llist.h"

// Initialize a new, empty LList, in dynamically allocated memory.
LList *llist_new(LList **self) {
    *self = malloc(sizeof (LList));
    if (self == NULL) { return NULL; }

    (*self)->front = NULL;
    (*self)->back = NULL;

    return *self;
}


// Append a value to the LList.  Creates a new node.
void llist_add(LList *self, void *v) {
    LLNode *node = malloc(sizeof (LLNode));
    assert(node != NULL);

    node->data = v;
    node->next = NULL;

    // Put this node at the back of the list.
    if (self->front != NULL) {
        self->back->next = node;
        self->back = node;
    } else {
        self->back = node;
        self->front = node;
    }
}


// Iterate over the LList to locate a node, and then remove it from the list.
void llist_remove(LList *self, LLNode *node) {
    LLNode *iter_node = self->front;
    LLNode *prev_node = NULL;

    while (iter_node != NULL) {
        if (iter_node == node) {
            if (prev_node != NULL) { prev_node->next = iter_node->next; }
            else { self->front = NULL; }
            free(iter_node);
            return;
        }
        prev_node = iter_node;
        iter_node = iter_node->next;
    }

}


// Insert a value after a particular node.
void llist_insert(LLNode *node, void *v) {
    LLNode *next = node->next;
    LLNode *new_node = malloc(sizeof (LLNode));
   
    new_node->data = v;
    new_node->next = next;
   
    node->next = new_node;
}


void llist_destroy(LList *self) {
    LLNode *iter_node = self->front;

    while (iter_node != NULL) {
        LLNode *next = iter_node->next;
        free(iter_node);
        iter_node = next;
    }

    free(self);
}


Testcase:
// llist_test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "llist.h"

#ifdef _WIN32
char *strdup(char *s);
#endif

int main(void) {
    LList *phone_nums;
    LLNode *iter;

    if (llist_new(&phone_nums) == NULL) { printf("Out of memory."); exit(1); }
    llist_add(phone_nums, strdup("123-4567")); // Yes, I should free() these later...
    llist_add(phone_nums, strdup("890-1234"));
    llist_add(phone_nums, strdup("567-8901"));
    llist_add(phone_nums, strdup("234-5678"));
       
        LLNode *temp = NULL;
    iter = phone_nums->front;
    while (iter) {
        printf("%s\n", (char*)iter->data);
        if (!strcmp("890-1234", (char*)iter->data)) { temp = iter; }
        iter = iter->next;
    }
    puts("");
   
    llist_insert(temp, strdup("BEEP BOOP"));
   
    iter = phone_nums->front;
    while (iter) {
        printf("%s\n", (char*)iter->data);
        if (!strcmp("567-8901", (char*)iter->data)) { temp = iter; }
        iter = iter->next;
    }
    puts("");
   
    llist_remove(phone_nums, temp);
   
    iter = phone_nums->front;
    while (iter) {
        printf("%s\n", (char*)iter->data);
        if (!strcmp("567-8901", (char*)iter->data)) { temp = iter; }
        iter = iter->next;
    }
   
   
    llist_destroy(phone_nums);
    return 0;
}

#ifdef _WIN32
char *strdup(char *s) {
        char *p = malloc(strlen(s) + 1);
        strcpy(p, s);
        return p;
}
#endif

Name: i_have_a_raging_boner 2011-08-21 12:26

That append is hella complicated. I would have done something like the following...

Node *append_my_anus(Node *llist, Node *malloced_list) {
    Node *p;

    if (listp = NULL)
        return malloced_list;
    for (p = listp; p->next != NULL; p = p->next)
        ;
    p->next = malloced_list
    return llist;
}

This code runs in linear time though.

Name: Anonymous 2011-08-21 12:29

>>37
What >>40 said. Perhaps you were looking for calloc? Probably not; just zero the members out.

>>35
self is not ambiguous. It's either a good pointer or NULL, just like the return of malloc. The fact you can tell the difference more easily just by glancing doesn't matter since you usually won't be (or at the very least shouldn't be) ``just glancing'' at a linked list constructor. It's not like it's complicated or anything like that.

Name: i_have_a_raging_boner 2011-08-21 12:34

>>42
What >>40 said. Perhaps you were looking for calloc? Probably not; just zero the members out.

Zero what out? The bytes or the bit pattern? I hate to tell you this chief, but ANSI/ISO C makes a distinction between the two. And an experienced C programmer would be able to tell you the rationale behind such apparent nonsense.

It's either a good pointer or NULL, just like the return of malloc.

Technically malloc() doesn't return the pointer. But I don't think you're ready for that level of C yet -(.

Name: Anonymous 2011-08-21 13:38

>>43
Technically malloc() doesn't return the pointer.
IHBT.

Name: Anonymous 2011-08-21 13:41

try this instead:


LList *llist_new() {
    LList *llist;

    llist = malloc(sizeof(LList));

    if (llist) {
        llist->front = 0;
        llist->back = 0;
    }

    return llist;
}

LList *phone_nums;

if ((phone_nums = llist_new()) == NULL) {
    printf("Out of memory."); exit(1);
}

Name: Anonymous 2011-08-21 13:45

>>45
llist = malloc(sizeof(LList));

This line of code will go down like your mom if the sign changes.

printf("Out of memory."); exit(1);

And this error message may not been seen if the underlying device is something other than a terminal.

But I'm sure a "programming professional" like yourself knows about stuff like this.

Name: Anonymous 2011-08-21 13:48

>>44
No you idiot. The pointer in malloc is local variable. It goes out of scope when malloc returns. What gets returned instead is what the pointer was pointing at. Cripes. Haven't you ever written a single line of C code? Haven't you ever actually taken the taken the time to read the ANSI/ISO C standard? Haven't you even taken the time to think instead of accusing people of trolling you?

I bet not. Now shut up and go help another customer you nowhere bitch. It's pretty obvious that you don't have the mental capacity to do anything more than that in life.

Name: Anonymous 2011-08-21 13:58

>>46

>sign changes
>other than a terminal.

3/10.

Name: Anonymous 2011-08-21 14:04

>>48
How? What happens if this is run on a *nix box? And what happens if the underlying device is something like a pipe or a socket? The code will block in its call to read() because the device is, by default, fully buffered.

Name: Anonymous 2011-08-21 14:06

>>48
Also, the sign change comments could from a bug that happened in some production level C code at work. But I doubt you would know something like this because you probably have never worked as a computer programmer for a major US firm. Now shut up and try to learn something you mental midget.

Name: Anonymous 2011-08-21 14:07

*comments came from*

Name: Anonymous 2011-08-21 14:12

>>45
The likelihood if printf succeeding when you've just ran out of memory is very small also you're going to screw up everything that isn't a terminal, use fprintf to stderr instead.

Also use EXIT_FAILURE instead of 1.

Name: Anonymous 2011-08-21 14:18

>>52
Or if your some language purist that believes in bullshit like Lisp, then do something like the following

(void)fprintf(stderr, "Out of memory\n");

Name: Anonymous 2011-08-21 14:23

#include <stdlib.h>

#include <ooc/lang/OutOfMemoryError.h>

int main(void) {
  int * p = malloc(1024 * sizeof(int));

  if (p == NULL)
    throw(new(OutOfMemoryError(),
              "main: malloc failed."));

  /* Work with p */

  free(p);

  exit(EXIT_SUCCESS);
}

Name: i_have_a_raging_boner 2011-08-21 14:28

>>54
The discussion revolved around C and not C++. I know it might be the same thing to a neanderthal like yourself. But really, it isn't.

Name: Anonymous 2011-08-21 14:31

>>55
That is ANSI-C.

Also the races with the greatest amount of neanderthal DNA are Whites and Asians who are the most successful, intelligent and industrious races so thank you for the compliment.

Name: Anonymous 2011-08-21 14:37

>>56
Really? I have a copy of the C90/99 standard right in front of me. Can you please cite the passasge or passages that support such extensions? Because, for whatever reasons, I can't seem locate it.

Name: Anonymous 2011-08-21 14:44

>>50
kodak_gallery_programmer detected.  Why did you lose the tripcode?

>>55
It's OOC, not C++.  But you are right, this is about C.

Name: Anonymous 2011-08-21 14:52

>>57
What extensions are you referring to? What you see there are some function calls, I'm sure there is something about creating and calling functions in the standard (you fucking moron).

>>58
No, it's C.

Name: i_have_a_raging_boner !!kCq+A64Losi56ze 2011-08-21 14:56

>>59
#include <ooc/lang/OutOfMemoryError.h>

This is a nonstandard C header you fucking idiot. It's a language extension because the function gets introduced into the code after the program completes its translation unit. Again, you haven't cited the actual C90/C99 passage that supports something like this.

Name: Anonymous 2011-08-21 14:58

>>58
I lost got rid of the headers because some brilliant mind decided to filter me out based on my tripcode. Also, I stand correct about it not being C++. I just saw the throw() function and assumed right away that the code was some kind of strange C++ dialect

Name: i_have_a_raging_boner 2011-08-21 15:04

>>59
It's not standard C you annoying little stupid fucker. Standard C is meant to be portable. Ie, I take a piece of code, and it should compile cleanly on a Linux Machine, a Windows Machine, and a Mac. This code isn't portable. I would have to install your system specific files in order to make it work.

Name: 37 2011-08-21 15:56

>>40
IHBT

so you're one of those zero-everything-out-before-use--just-in-case-faggots. I pity you

Name: Anonymous 2011-08-21 16:03

>>63
wow you're a huge fag. go get your face raped.

Name: i_have_a_raging_boner !!kCq+A64Losi56ze 2011-08-21 16:06

>>63
so you're one of those zero-everything-out-before-use--just-in-case-faggots. I pity you

I'm guessing because he wants to have the bit pattern zero. I hate to break it to you, but 0 bytes and a bit pattern of 0 can be two different things. Failure to make a distinction between the two can lead to some pretty ugly bugs in production level C code.

Name: Anonymous 2011-08-21 16:11

Technically malloc() doesn't return the pointer
That's maybe the stupidest thing I've ever seen. Damn trolls. Damn /prog/

Name: i_have_a_raging_pointer !!kCq+A64Losi56ze 2011-08-21 16:19

>>66
How do you minimum wage bitch? Inside of malloc() there is a pointer. This variable has local scope. However, what it points to has doesn't. When malloc() returns, the local pointer variable goes out of scope. However, the object that it points to doesn't. For further information, please refer to the sample malloc() implementation on page 187 in the second edition of the book "The C Programming Language" by K & R.

Now STFU and learn something from someone who works at a major US firm as a computer programer.

Name: Anonymous 2011-08-21 16:20

>>66
*How so you minimum wage bitch?"

Name: Anonymous 2011-08-21 16:42

I fucking hate you faggots.

Name: Anonymous 2011-08-21 16:55

0 bytes and a bit pattern of 0 can be two different things
List one or more platforms where this is the case, and I will remember to stay away from them.

Same with null pointers being not all 0s.

Name: Anonymous 2011-08-21 17:03

>>70
Immediately after I posted that I thought someone might think of floating-point formats but then I checked IEEE754 and 0 is indeed the pattern with all zeros.

The people who design these things tend to be sane, and I don't care if my code doesn't work on some fucked-up platform where things are not.

Name: Anonymous 2011-08-21 17:07

>>67
I don't care about malloc's local variables, why should I. It's a function and it works. It allocates me memory. It returns a pointer to memory.

Please go out from the internet.

Name: Anonymous 2011-08-21 17:09

what it points to has doesn't

Name: i_have_a_raging_boner !!kCq+A64Losi56ze 2011-08-21 17:40

>>72
It returns a pointer to memory
Well saying that it returns a pointer is just plain retarded and it is also indicative of the fact you've never actually ever written any kind of production level C code for any firm.

Homer, it's one thing to google and memorize shit. It's an entirely different thing to actually do it. You might want to consider that sometime before you make another uneducated statement you minimum wage bitch.

Now go off and help another customer you mental midget.

Name: Anonymous 2011-08-21 17:44

>>74
Well saying that it returns a pointer
lolz.  Reminds me of the last C thread where kodak_gallery_programmer got owned.  Too lazy to dig it up.  But if you hadn't figured it out yet: disregard everything he says.

Name: Anonymous 2011-08-21 17:46

>>74
WHAT HAPPENS IF I SCREAM TO YOUR FACE AND DON'T GIVE A HINT OF WHERE THE ERROR IS?

Name: Anonymous 2011-08-21 17:49

>>75
Oh aren't we cool. We can lolz on the internet. I bet a lot of potential employers must be impressed by your internet slang. I mean, I would be. Anyone that uses lolz clearly must be a brilliant engineer!

Now tell us again why you aren't doing something related to programming for a living.

Name: Anonymous 2011-08-21 18:45

>>60,62
So if I ``inline'' the header and it is all ANSI-C will you then forgive me oh great one? Or isn't extern a part of the standard any longer?

Name: i_have_a_raging_boner !!kCq+A64Losi56ze 2011-08-21 19:26

>>78
So if I ``inline'' the header and it is all ANSI-C will you then forgive me oh great one? Or isn't extern a part of the standard any longer?


Huh? Are you saying/implying that using 'extern' will result in an 'inline'? BTW, my whole beef was that while the code was written in C, it wasn't C (in the strictest sense). You see?

Name: Anonymous 2011-08-21 19:30

With that, I'm going back to writing some code. Someone let me know whe amateur hour is over.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List