Shivam Kaushik
Shivam Kaushik

Reputation: 29

How is sizeof(char *) and sizeof(char) different?

#include<stdio.h>
main()
{
    char *str[]= {"Frogs","do","not","die","they","croak"};
    printf("%d %d %d",sizeof(str),sizeof(str[0]),sizeof(char));
}

output is:

48 8 1

According to size of char being 1 byte and there are six character variables so total size of array should be 6 instead of 48!

Upvotes: 1

Views: 8382

Answers (5)

Sourav Ghosh
Sourav Ghosh

Reputation: 134316

Point 1

sizeof retruns the size of the data type, not the amount of memory allocated to the variable.

For what it's worth, if you want to measure the length of a string, (i.e., the number of elements inside a string), you can use strlen()

Point 2

Don't get confused with the datatypes.

  • str is an array of pointers. It holds 6 pointers, so the sizeof will give 6 * sizeof(<pointer type>) which is 6 * 8 or 48 on 64-bit systems.
  • str[0] is a pointer, so sizeof str[0] equals sizeof(char *) which is 8 on 64-bit systems.
  • C standard guarantees sizeof(char) to be equal to 1.

Point 3

sizeof operator returns a size_t. You need to use %zu format specifier to print that portably and reliably.

Upvotes: 10

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

An array declared like

char *str[]={"Frogs","do","not","die","they","croak"};

has type char *[6]. that is it is an aray of 6 pointers to characters. Consequently str[0] has type char * that is it is a pointer.

Thus

sizeof( str[0] )

is equivalent to

sizeof( char * )

and in your system is equal to 8.

In turn

sizeof ( str )

is equivalent to

6 * sizeof( char * )

and equal to 48.

Take into account that in this initializer list

char *str[]={"Frogs","do","not","die","they","croak"};

string literals are implicitly converted to pointers to their first characters.

On the other hand if you will write for example

sizeof( "Frogs" )

then the expression will be equal to 6 becuase 1) string literals are character arrays that include terminating zero and 2) within the operator sizeof they are not implicitly converted to pointers to their first characters, they are considered as arrays.

You could define a two dimensional array of strings the following way

char str[][6] = { "Frogs", "do", "not", "die", "they", "croak" };

In this case

sizeof( str[0] )

would be equal to 6 and

sizeof( str )

would be equal to 36 because in this case str is an array of elements of type char [6]

Pay attention to that in the last case you may change elements of the array the following way

str[0][0] = 'f';

while when you have an array of pointers to string literals (as in your original post) you may not write

str[0][0] = 'f';

because string literals are immutable.

And one more about the sizeof operator. According to the C Standard (6.5.3.4 The sizeof and alignof operators)

2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

Thus being applied to an array the operator yields the number of bytes the array occupies. It does not yield the number of elements in the array. If you want to get the number of elements in an array you should use expression

sizeof( array ) / sizeof( array[0] )

or

sizeof( array ) / sizeof( *array )

Upvotes: 0

unwind
unwind

Reputation: 399803

It seems you're on a 64-bit system, where sizeof (char *) is 8.

This explains the first value, since sizeof str is the size of the object str, which has type char *[6]. So you're getting the size as 48, which is of course 6 * 8.

Also, the proper way to printf() values of type size_t, which is what sizeof returns, is with %zu.

Upvotes: 3

chqrlie
chqrlie

Reputation: 144715

The printf format specifier %d is inappropriate for the argument values sizeof(str) and sizeof(str[0]) whose type is size_t.

You should either use %zu or cast the arguments as (int).

There are more problems with your code:

  • the return type for main must be specified as int.
  • the type of str should be const char *str[].
  • You should add a \n to the printf format to ensure that output id properly flushed on all systems.

Here is an improved version:

#include <stdio.h>
int main(void) {
    const char *str[] = { "Frogs", "do", "not", "die", "they", "croak" };
    printf("%zu %zu\n", sizeof(str), sizeof(str[0]));
}

It should output 24 4 or 48 8 on respectively 32 bit and 64 bit systems, and potentially other values on more exotic systems. The first number is the size of 6 pointers to const char and the second, the size of a single such pointer.

The size of the strings themselves can be determined at compile for constant immediate strings and defined arrays only as direct arguments of sizeof. In other cases, you must use strlen() to compute the string length, assuming they do not contain embedded NULs, and add 1 for the final '\0'.

Upvotes: 2

juanchopanza
juanchopanza

Reputation: 227390

str is a length-6 array of pointers to char. Its total size is 6 times the size of a pointer, which gives 48 on your platform.

Upvotes: 3

Related Questions