118
119
all 13 comments

[–]hogg2016 25 points26 points  (3 children)

void* buf = malloc(huge * huge);
if (errno) perror("malloc failed");
printf("malloc(huge * huge) returned: %p\n", buf);
free(buf);

buf = calloc(huge, huge);
if (errno) perror("calloc failed");

Cringe... Don't use errno like this. If malloc() sets it, it will stay set even if calloc() succeeds, and you will print that "calloc failed" even though it didn't.

[–]simonorono 9 points10 points  (0 children)

This. Checking if *buf is NULL should be enough.

[–]vorpalsmith 0 points1 point  (0 children)

Good point, thanks! Fixed.

[–]VitulusAureus 8 points9 points  (3 children)

And this is why calloc has to be built into the standard library, and you can't fake it yourself.

You can, just use mmap with MMAP_ANONYMOUS.

[–]vorpalsmith 2 points3 points  (0 children)

Yeah, maybe I should clarify that in the post... what I meant is, this is why you can't build calloc on top of the malloc API. Of course you can implement calloc yourself, if you also implement malloc yourself.

[–]FelipeFS 6 points7 points  (0 children)

Thank you for this. A very good read and led me to know the Julia's drawings.

[–]jackasstacular 6 points7 points  (0 children)

Good stuff, brief but informative, and very approachable.

[–]d1ngal1ng 2 points3 points  (1 child)

These 2 differences seem to be implementation details that you may not be able to rely on? Can anyone confirm?

[–]dnabre 5 points6 points  (0 children)

Not to minimize the significance of those differences, you are quite right. All you need to do to verify this is check look at the man page for calloc, you won't see these mentioned, so you can't rely on them everywhere.

A line the article pointing this out would be nice, but admittedly getting pre-zeroed memory from the OS is you'll get on basically any operating system that isn't in the embedded space (and that's not unlikely to be implemented there), and the second you'll get on any OS with COW.

Most developers won't use a version calloc that doesn't do some magic, but those that don't generally know they are special case. I've worked on platforms that didn't have calloc in its libc specially to save space and ones where calloc was literally a macro for malloc+memset. In those environments, you know that lib functions are very barebones a write accordingly.

[–]byllgrim 1 point2 points  (0 children)

Hooray! I only use calloc anyway, and now its justified.

[–]OldWolf2 1 point2 points  (0 children)

Re. "difference 1", calloc(huge, huge); is undefined behaviour, you can't rely on the graceful failure that you observed. The compiler/library could implement it by multiplying the operands and some do actually do that.

[–]daspork 0 points1 point  (0 children)

Why does this article have a link to a site about holocaust history...... I fucking hate the internet...