2

I came across the following code snippet. I have 2 questions about it and need some help.

int *loc_buff;
loc_buff = malloc(sizeof(loc_buff[0]) * COUNT_EACH * n);
memset(loc_buff, -1, COUNT_EACH * sizeof(int) * n);
  1. Is it correct to use sizeof(loc_buf[0]) instead of sizeof(int)?
  2. Will this memset resets all loc_buf to -1?

Thanks.

Zack
  • 1,205
  • 2
  • 14
  • 38
  • 3
    Question is not bad. Why down-votes? – Pranit Kothari Oct 04 '14 at 02:48
  • I am not a good programmer in C, though just started using it. One thingy I can think of is, when one uses `sizeof(*loc_buff)`, it allows one to make away with, if at later stage, I change the type of `*loc_buff` from being pointer to an `integer`, to pointer to a `char/other data type`. Still, you need not worry about the memory being allocated, since `*loc_fuff` is already defining it's size as either `4(for integers)/1(for character/etc`. Hence a single change in the data type for the variable, will not cause any side effects to the rest of the implemented code :-) – nIcE cOw Oct 04 '14 at 03:24
  • If one writes `sizeof(int)`, then if at later stage, once changes the type of the variable from `int` to a `newType`, then one needs to scroll through the code, to change the respective type in `sizeof(newType)` thingy as well. – nIcE cOw Oct 04 '14 at 03:27

2 Answers2

4

is it correct to use sizeof(loc_buf[0]) instead of sizeof(int)?

Technically, this is correct, because it's the same thing: sizeof(loc_buf[0]), sizeof(*loc_buf), and sizeof(int) are all the same. However, since in both cases the size is taken to deal with the same dynamically allocated buffer, this is inconsistent. One should rewrite both sizeofs in the same way of your choice; it does not matter which one you prefer.

Will this memset resets all loc_buf to -1?

Yes, it would. The situation is not entirely straightforward, though: the value that you supply gets converted to unsigned char before being set to the elements of the memory block. In two's complement representation -1 consists of all bits set to 1. this gets converted to an unsigned char with all ones, which gets set in all bytes in the block. Now the entire block consists of bytes with all their bits set to ones. When these bytes get re-interpreted as ints, they become -1s again.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

Operator sizeof has two forms: sizeof(type) and sizeof expression. In your case you can use sizeof(int) or sizeof loc_buff[0] or sizeof *loc_buff with identical results. Note that the () are completely optional when the argument of sizeof is an expression (not a type). sizeof operator has high priority, which makes those () redundant in most cases (including your example).

As for memset... formally it is not guaranteed to set loc_buff elements to -1 in general case. This memset is guaranteed to fill the memory with 0xFF...F bit pattern, but what that bit pattern means when interpreted as an int object is implementation-dependent. On a 2's-complement machine this is indeed -1, but on non-2's-complement machine it is something completely different.

From the very pedantic point of view, the only portable use memset has with non-char integer arrays is setting everything to 0.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • is that over concern? are there any non-2's-complement machines still existing in the world? – Jason Hu Oct 04 '14 at 03:09
  • @HuStmpHrrr: Well, this is the question that should be directed at C standardization committee. They continue to meticulously maintain support for 1's-complement and signed magnitude representations (they are in C11). If they still consider it necessary, then it must be necessary. – AnT stands with Russia Oct 04 '14 at 03:11
  • 1
    You can also take a look here http://stackoverflow.com/questions/12276957/are-there-any-non-twos-complement-implementations-of-c – AnT stands with Russia Oct 04 '14 at 03:16