3

I was wondering, do most implementations of calloc treat the size as an alignment too, and round it up to the next supported granularity?

If so, then do they round up to the next power of 2, or do they round to the next multiple of 8 or 16?

If calloc keeps the parameter the same, then how does that even work? Wouldn't your data then be unaligned?

Thank you!

Daniel Trebbien
  • 38,421
  • 18
  • 121
  • 193
user541686
  • 205,094
  • 128
  • 528
  • 886

2 Answers2

5

sizeof is defined to yield the size of an object within an array -- in other words, it already accounts for any padding that's needed for proper alignment. So if sizeof(foo) is 23 for some object foo, then your processor must be byte-aligned. (On the other hand, if you're passing 23 because you just think it's a good value to pass in, then good luck to you; you're on your own.)

Dan Breslau
  • 11,472
  • 2
  • 35
  • 44
  • Haha yeah, I feel lucky. :) So that means it's the programmer's responsibility to pass in an aligned value as the second parameter, correct? There's no formal specification for the behavior of the runtime if it's an odd number but the processsor requires 4-byte alignment? – user541686 Jan 04 '11 at 02:06
  • 1
    If you're playing with bytes like this, without using `sizeof` appropriately, then I'm worried about what else you might be doing -- trying to second-guess how the compiler computes offsets into a struct, for example? But that aside: if 23 is too large, then the only problem you have is that you're wasting space. If it's too small, you're not just on your own; you're doomed to failure. – Dan Breslau Jan 04 '11 at 02:10
  • @Dan: I'm reading section 6.5.3.4 The `sizeof` operator of the C standard now, but do not see mention of alignment consideration in the calculation of `sizeof`. Where is it mentioned that `sizeof` accounts for alignment? – Daniel Trebbien Jan 04 '11 at 02:14
  • Haha I'm not actually trying this; I'm was just writing my own `calloc` and wondered how to handle this situation. Thanks for the reply! :) – user541686 Jan 04 '11 at 02:18
  • 1
    @Daniel: See arrays under "representation of types". – R.. GitHub STOP HELPING ICE Jan 04 '11 at 02:27
  • @Daniel: In 6.5.3.4, paragraph 3: "When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding." – Dan Breslau Jan 04 '11 at 03:05
  • @Lambert: The only tricky part of implementing `calloc()` yourself is to check for overflow in the multiplication. Otherwise, it's just a straightforward multiplication followed by a call to `malloc()` and `memset()`. – caf Jan 04 '11 at 04:15
  • @caf: If I don't do the overflow check, it'll still have correct behavior for correct input, won't it? (Because I can't think of a valid situation that would overflow...) – user541686 Jan 04 '11 at 04:26
  • 2
    @Lambert: I don't believe so - the standard states that *"If the space cannot be allocated, a null pointer is returned"*. There is no requirement on the user that `nmemb * size` be `<= SIZE_MAX`, and therefore no get-of-jail card for the implementation. – caf Jan 04 '11 at 04:32
  • @caf: Ah, okay, thanks for the heads-up -- I certainly didn't think of that! :) – user541686 Jan 04 '11 at 04:33
  • @Daniel: I don't think there's an explicitly mentioned requirement for structure padding in the standard anywhere, though padding is explicitly permitted (C99 6.7.2.1/13 and 6.7.2.1/15). However, since elements of an array must each be properly aligned, any structure needs to have whatever padding is necessary so that an array of those structure elements will end up with each element properly aligned. That padding needs to be accounted for in the value returned by the `sizeof` operator. – Michael Burr Jan 04 '11 at 04:35
3

As far as alignment is concerned, calloc(1000, 23) is precisely equivalent to malloc(1000 * 23). If the implementation decides to "align" the size in some way, it will snap the total size of 23000 to some greater implementation-defined value. There's no special treatment applied to the second parameter of calloc (or to the first, for that matter).

Snapping 23 to 24 in calloc(1000, 23) would really mean snapping 23000 to 24000 (in terms of total size). There's no reasonable practical implementation that would require adding the entire 1000 for alignment purposes.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765