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.
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;
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;
}
>>11
The implementation of closures is left as an exercise for the reader.
>>12-13 (void*)0 is guaranteed to be NULL, but 0 is not.
Name:
Anonymous2011-08-19 21:44
>>13
Then you're a fucking moron, holy shit, please don't have children but if you do please put them up for adoption as it is probably against the Geneva convention to have someone as retarded as you raise children you're dumber than the African Americans who shoot each other over gang colors in South Central holy shit are you fucking kidding me how can you not realize something that simple why don't you write out every sizeof as well then holy shit in fact why don't you just expand every macro while programming let me guess you're the type who writes 1 instead of sizeof(char) just because it says it's always 1 in the standard well I got news for you mister you are a fucking dickhead please never write code or post again, actually please kill yourself we don't need more fast food burger flippers posting on this board go play with some fucking barbie dolls you fucking mental midget go suck a fat cock you fucking bitch seriously FUCKOFFFAGGOT.
>>16
you'd have a point if NULL was typed, but it's just a #define.
0x might be changing this. Not sure. Couldn't give 2 shits about C++ anymore.
Name:
Anonymous2011-08-19 22:15
>>16
I do consider char to be 8 bits because my code runs on sane platforms -- for everything else I use uintXX_t due to compiler differences.
I don't consider 0 == NULL to be a large problem since you can just not map a page at virtual address 0 so that dereferencing null will cause a segfault.
>>20
You think it's cool to needlessly obfuscate your code with stuff most people know? If you're going to obfuscate at least do it right instead of some half-assed faggotry.
Awesome code. Great size. Looks concise. Efficient. Elegant. Keep us all posted on your continued progress with any new code factoring or compiler optimization. Show us what you got man. Wanna see how freakin' expressive, efficient, concise and elegant you can get. Thanks for the motivation.
>>25
That's the point, he's only obfuscating it for people who hardly know any programming and it makes him look like a fucking retard to everyone else.
>>34
Yes, but this version is less explicit about what can be returned. self is ambiguous in this implementation; you'd have to do the extra work of seeing and understanding that it was malloc'd and could fail, and what the consequences of that failure mean. The other version makes an explicit distinction -- either you're getting a(n) LList object, or you're getting NULL, just by glancing.
>>31,35
Explicitly returning NULL is a superior way of checking the malloc return code. What if you malloc n things, are you going to nest n if tests? Holy shit you don't know even know basic error checking, you're a fucking retard, please get the fuck out and never come back, you post shit all the time, you give horrible advice and you're an absolute shit programmer.
>>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_boner2011-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:
Anonymous2011-08-21 13:38
>>43 Technically malloc() doesn't return the pointer.
IHBT.
Name:
Anonymous2011-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);
}
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:
Anonymous2011-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.
>>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:
Anonymous2011-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:
Anonymous2011-08-21 14:07
*comments came from*
Name:
Anonymous2011-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:
Anonymous2011-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:
Anonymous2011-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_boner2011-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.
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:
Anonymous2011-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.
>>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:
Anonymous2011-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).
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:
Anonymous2011-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_boner2011-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.
>>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:
Anonymous2011-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/
>>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.
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.
>>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:
Anonymous2011-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.
>>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.
>>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.
>>74 WHAT HAPPENS IF I SCREAM TO YOUR FACE AND DON'T GIVE A HINT OF WHERE THE ERROR IS?
Name:
Anonymous2011-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:
Anonymous2011-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?
>>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:
Anonymous2011-08-21 19:30
With that, I'm going back to writing some code. Someone let me know whe amateur hour is over.
Name:
Anonymous2011-08-21 19:30
*when*
Name:
Anonymous2011-08-21 19:37
>>79 BTW, my whole beef was that while the code was written in C, it wasn't C (in the strictest sense).
I hate you, Zhivago, I truly do.
>>82
Why flatter him by comparing him to Zhivago? This guy is an idiot.
Name:
Anonymous2011-08-21 21:26
>>79
No, I was asking that if I explicitly copy and paste the header file into the source file and that the header file is valid ANSI-C if then you might accept the entire file as C?
Name:
Anonymous2011-08-21 21:30
>>83
Why because I actuall know what I'm talking about you mental midget? Maybe you should actually take a look at the ANSI/ISO C standard instead of trying to argue with someone who does this shit for a living. Now shut up and go clean another toilet.
>>84
No matter how you do it, nonstandard C functions are nonstandard C functions. I would say look at how some of the more popular pieces of open source software handles nonstandard C functions. But I'm afraid that you, along with the other hoshead that is calling me an idiot, wouldn't be able to tell what the programmers do in cases like this.
Name:
Anonymous2011-08-21 21:48
>>84-86
I don't code for the C virtual machine as defined in the standard, I code for real architectures. You know what that is? I bet you don't. I bet you're going to explode in a fabulous autistic homosexual rage when I tell you that C is portable assembly. But enough of this, off you go now, your skills in pure C are needed at cash register 6.
Name:
Anonymous2011-08-21 21:52
>>86
So I can't link with functions I have written in other C files? Is that really outside the standard?
>>87 I don't code for the C virtual machine as defined in the standard
I think you mean the C abstract machine their chief.
I code for real architectures
Programming the lego mindset robot doesn't count as a *real architecture*.
You know what that is? I bet you don't
OMFG, look at that code that does a simple file lock! There are over 5 include guards! And each include guard has a different way to handle the lock for each type of *nix variant!
Name:
Anonymous2011-08-21 22:01
>>89
*I think you mean the C abstract machine their chief*.
>>1
Improvements: OMG ENTERPRISE
Insert and add should return a ``correct or incorrect operation'' exit value, as new does.
Add an interface for getting elements by number of element. If you don't do this you are going to BREAK ENCAPSULATION and this is considered bad practice and forces the programmer, i.e. you to do things like
iter = phone_nums->front;
while (iter) {
printf("%s\n", (char*)iter->data);
if (!strcmp("567-8901", (char*)iter->data)) { temp = iter; }
iter = iter->next;
}
So now I can do that kind of thing without breaking encapsulation: LLNode *cur_item = llist_top(phone_nums);
while (cur_item != NULL) {
printf("%s\n", (char*)cur_item->data);
cur_item = llist_next(cur_item);
}
Anything wrong with it now?
Name:
Anonymous2011-08-21 23:24
>>89
Alright fucktard, go play in the traffic. Now.
You could also #include <errno.h> and exit with that code (but note that the perror call may modify the value, so you'd have to store it in a temp first.)
>>102
The thread may be somewhat /prog/, but it really is reddit-quality.
Name:
Anonymous2011-08-22 7:38
I would recommend to stuff the [url=http://paste.pocoo.org/show/462370/]pointers to nodes in the elements of the list itself[/url], as in the Linux kernel (the FreeBSD, which is using macros is also interesting but probably less optimized).
>>106
Yes it is you minimum wage bitch. The first mention of 'offsetof' can be found under item 18, section 6.7.2.1 Stucture and union specifiers in the ISO/IEC 9899 standard.
Now shut up and go serve another customer you fucking moron.
>>108
And you've been making the same ignorant/uneducated statements for the past few years. Either get with the program or take up something that is a tad bit easier. Like working a cash register at Target.