Live data from Hacker News

Why does calloc exist?

vorpus.org

81–90 of 141 posts

Re: Why does calloc exist?

#81
post #55
post #32

buf = calloc(huge, huge); if (errno) perror("calloc failed"); printf("calloc(huge, huge) returned: %p\n", buf); free(buf); This has a flaw. errno doesn't magically get reset to zero. You should check the return value of calloc, then use errno. Checking if(errno) is not the right way to determine if there was an error.

Its [errno's] value is significant only when the return value of the call indicated an error (i.e., -1 from most calls; -1 or NULL from most library functions); a function that succeeds is allowed to change errno.

Note the difference between "is allowed" vs "must".

If you write a program that relies on this behaviour you're going to have a hard to track down bug at some point.

Re: Why does calloc exist?

#82
post #81
post #55

Earlier quoted context omitted.

Its [errno's] value is significant only when the return value of the call indicated an error (i.e., -1 from most calls; -1 or NULL from most library functions); a function that succeeds is allowed to change errno.

Note the difference between "is allowed" vs "must". If you write a program that relies on this behaviour you're going to have a hard to track down bug at some point.

That's even stronger case for not relying on errno to catch errors.

The code should be something like this:

    buf = calloc(huge, huge);
    if (!buf)
        perror("calloc failed");
    printf("calloc(huge, huge) returned: %p\n", buf);
    free(buf);

Re: Why does calloc exist?

#83
post #82
post #81

Earlier quoted context omitted.

Note the difference between "is allowed" vs "must". If you write a program that relies on this behaviour you're going to have a hard to track down bug at some point.

That's even stronger case for not relying on errno to catch errors. The code should be something like this: buf = calloc(huge, huge); if (!buf) perror("calloc failed"); printf("calloc(huge, huge) returned: %p\n", buf); free(buf);

[deleted]

Re: Why does calloc exist?

#84

Earlier quoted context omitted.

At the same time why would you ever opt to malloc & memset instead of calloc? calloc might have clever optimizations, whereas malloc + memset won't. Intentionally choosing something slower, buggier, and that requires more work on your part is moronic.

Predictability sometimes trumps optimizations. For a striking illustration of this, see timing attacks.

This was approach that OpenSSL does (it had its own memory management routines), and it already caused security vulnerabilities, not to mention performance issues.

Rule of thumb: if you need to allocate memory region that will be overwritten anyway (for example reading a file) use malloc(). If you need a zeroed memory, use calloc().

As long as you rely on guarantees provided by the calls and use the right call for right use case you get predictability and very often optimization.

Re: Why does calloc exist?

#85
post #58

Earlier quoted context omitted.

Predictability sometimes trumps optimizations. For a striking illustration of this, see timing attacks.

Exactly. I would avoid using calloc simply because I don't know what it actually does .

You know what it does:

    The calloc() function contiguously allocates enough
    space for count objects that are size bytes of memory
    each and returns a pointer to the allocated memory.
    The allocated memory is filled with bytes of value zero.
You should not care how it does it.

Re: Why does calloc exist?

#86
post #82
post #81

Earlier quoted context omitted.

Note the difference between "is allowed" vs "must". If you write a program that relies on this behaviour you're going to have a hard to track down bug at some point.

That's even stronger case for not relying on errno to catch errors. The code should be something like this: buf = calloc(huge, huge); if (!buf) perror("calloc failed"); printf("calloc(huge, huge) returned: %p\n", buf); free(buf);

Yes, my post above was agreeing that you should check the error condition of the return value, rather than relying on errno to be cleared on success.

Re: Why does calloc exist?

#87
post #58

Earlier quoted context omitted.

Exactly. I would avoid using calloc simply because I don't know what it actually does .

The implementation details of malloc aren't specified as part of its interface either...

Which is why high-end games do not use generic system malloc; in general we link custom allocators whose source code we control and that are going to behave similarly on all target platforms.

(In fact we go out of our way to not do malloc-like things in quantity unless we really have to, because the general idea of heap allocation is slow to begin with.)

Re: Why does calloc exist?

#88
post #85
post #58

Earlier quoted context omitted.

Exactly. I would avoid using calloc simply because I don't know what it actually does .

You know what it does: The calloc() function contiguously allocates enough space for count objects that are size bytes of memory each and returns a pointer to the allocated memory. The allocated memory is filled with bytes of value zero. You should not care how it does it.

Spoken like someone who does not ship fast software!

Re: Why does calloc exist?

#89
I suppose another alternative would be for memset() to check if the page is already mapped to the zero page, and to do nothing if it is. There are some bitset-related data structures that should make that pretty efficient.

Re: Why does calloc exist?

#90
post #88
post #85

Earlier quoted context omitted.

You know what it does: The calloc() function contiguously allocates enough space for count objects that are size bytes of memory each and returns a pointer to the allocated memory. The allocated memory is filled with bytes of value zero. You should not care how it does it.

Spoken like someone who does not ship fast software!

There's a saying that is often misused, but applies here: "premature optimization is a root of all evil"

You first write your code using standard system functions, using the right calls for what you're doing. If after that performance of the code is bad because of calloc() only then you roll out your own implementation (most likely in assembly), and accept that in the future your code might not work well, because something in your OS has changed since you wrote your code.

Post reply on HN