Why write `sizeof (char)` if char is 1 by standard?

I did some C-coding, and after reading some C code, I noticed that there are code fragments, such as

char *foo = (char *)malloc(sizeof(char) * someDynamicAmount); 

So, I want to ask, what other C-ish way to allocate memory for char array? Use sizeof(char) and presumably future code with any standard changes or omit it and use the number directly?

+49
c coding-style
Aug 30 '11 at 13:23
source share
12 answers

More cish will be

 char* foo = malloc(someDynamicAmount * sizeof *foo); 

referring to a variable, not to a type so that the type is not needed. And without casting the result malloc (which is C ++ ish).

+64
Aug 30 '11 at 13:27
source share

I am doing sizeof(char) to make intentions clear. If someone decides that he wants foo to be int , he knows that he will need sizeof(int) for him to continue working.

or omit it and use the number

Also, this is not a good coding practice for using magic numbers.

+29
Aug 30 '11 at 13:25
source share

IMHO it is best to write sizeof(*foo) . Then you are also covered if the change type foo and sizeof are not fixed.

+25
Aug 30 '11 at 13:28
source share

For comparison:

 float*baz = malloc(sizeof(float) * someDynamicAmount); int *bar = malloc(sizeof(int) * someDynamicAmount); char *foo = malloc(sizeof(char) * someDynamicAmount); 

Vs:

 float*baz = malloc(sizeof(float) * someDynamicAmount); int *bar = malloc(sizeof(int) * someDynamicAmount); char *foo = malloc(someDynamicAmount); 

I like the first version. Do you prefer the second?

+11
Aug 30 '11 at 13:27
source share

You are right, according to the standard, multiplication is irreligious. However, it is like a habit that someone has entered into to be consistent. If you always use sizeof() , regardless of type, you will never forget.

 char *foo = (char *)malloc(sizeof(char) * someDynamicAmount); int *bar = (int *)malloc(sizeof(int) * someDynamicAmount); 
+7
Aug 30 '11 at 13:26
source share

Common idiom

 T *p = malloc(N * sizeof *p); 

or

 T *p; ... p = malloc(N * sizeof *p); 

This way you don't have to worry about type.

+7
Aug 30 2018-11-11T00:
source share

Citation standard C99 , section 6.5.3.4 The sizeof operator:

When applied to an operand with type char, unsigned char or signed char, (or its qualified version), the result is 1 . When applied to an operand with an array of type, the result is the total number of bytes in the array. When applied to an operand that has a structure or type of union, the result is the total number of bytes in that object, including the inner and back pad.

That is, sizeof char == 1 by standard, not by implementation. Therefore, it is absolutely correct to omit sizeof(char) when calling malloc() for characters and in similar cases. IMHO, it is very unlikely that the future C standard will allow char to be implemented, since too much code already depends on it as 1, and backward compatibility is very important in C.

So the question is only about style, not about correctness, and here I support AProgrammer's answer .

+2
Mar 26 2018-12-12T00:
source share

Writing sizeof(char) not a “future check” of your code for possible changes to the standard. Usually this is a sign of a complete misunderstanding of what sizeof means and the entire fundamental model of memory objects in C - what is called type representation in the language of the standard C. The only reason is that the sizeof operator exists or makes sense, since C indicates objects that have a "representation "in memory in terms of the smallest possible element, which is equal to unsigned char . If not for this, the repository would be much more abstract and there would be no use of sizeof and the associated pointer arithmetic.

sizeof defined in char units, i.e. sizeof(T)==N means that type T takes N char s. In light of this, sizeof(char) is absolutely stupid; he is trying to measure how much char a char takes.

+1
Aug 30 '11 at 17:41
source share

It all depends on the coding style. There are several styles.

To answer the question, people write

 malloc(n * sizeof(char)) 

save all your code that malloc uses. Next time they may need an int , and then they can write the code in the same way

 malloc(n * sizeof(int)) 

So the reason this is being done is to keep the coding style consistent. Despite the fact that sizeof(char) really always guaranteed to be 1, and therefore it is superfluous. This is a way to write self-documenting code.




However, the most common way to use malloc in C is perhaps

 type* t = malloc(n * sizeof(*t)); 

or 100% equivalent:

 type* t = malloc(n * sizeof *t); 

Since the sizeof operator is not evaluated for side effects, this code is safe, although the variable t is not yet initialized.




The third possible style is pedantically correct, which the pointers of the array will use, because what we select is actually an array:

 type (*t)[n] = malloc( sizeof(type[n]) ); 

This is perhaps the most correct way, since it concerns the correctness of the text. The size of the array is allocated, and we point to the selected array with an array pointer.

However, the problem with this style is that array pointers add extra complexity to the syntax: you will need to cancel this array as (*t)[i] instead of t[i] . This makes it difficult to read the code. (And also, as a note, if n is not an integer constant expression, the code will not compile on older legacy C compilers.)

0
Oct 27 '17 at 13:02 on
source share

The coding style can also be written as: -

 char *foo = (char *)malloc(1 * someDynamicAmount); 

But this is done so that the dynamically allocated memory can be increased in accordance with the absence of the basic data type that is required. if u wants to increase 100 char, it will increase by 100 char. If this may not be necessary, but if we write 101 or 102, this will lead to memory loss. executing it in accordance with the main data type will not waste time on free memory space

-2
Aug 30 '11 at 13:32
source share

The standard deliberately obscures the sizes of conventional types. [ Wikipedia ]

Although it is unlikely that the size of a char will not change, but the size of short has changed. The idiomatic way is:

 type_t *foo = malloc(sizeof(type_t) * someDynamicAmount); 

for any type (general or complex) type_t or

 type_t *foo = malloc(sizeof(*foo) * someDynamicAmount); 

So that you can later make changes to the foo type and change it in only one place.

-2
Aug 30 '11 at 13:33
source share

Think of unicode and multibyte strings. If char represents one character in a string, it can actually occupy more than one byte, resulting in sizeof ()> 1

-7
Aug 30 2018-11-11T00:
source share



All Articles