torayeff
torayeff

Reputation: 9702

C++ strlen(ch) and sizeof(ch) strlen

I have this code:

int main()
{
    char ch[15];
    cout<<strlen(ch)<<endl; //7
    cout<<sizeof(ch)<<endl; //15
    return 0;
}

Why does strlen(ch) give different result even if it is empty char array?

Upvotes: 0

Views: 2180

Answers (6)

Lin GU
Lin GU

Reputation: 89

The difference between sizeof and strlen in C++:

1) sizeof is a operator, strlen is a function;

2) The return type of sizeof is size_t,and it is defined (typedef) as unsigned int in its header; It gets the byte size of the memory allocation which can maximize to accommodate this object to be created in memory;

3) sizeof can use type as a parameter, while strlen can only use char pointer (char*) as a pointer, and it must be ended as '\0'; sizeof can also use function as a parameter, for instance:

short f() {return 100;} 
std::cout << "sizeof(f()): " << sizeof(f()) << std::endl;
//The result will be sizeof(short), which is 2.

4) If char array is a parameter, it will not be degraded by sizeof, while strlen will degrade it as a char pointer;

5) The result of strlen will be calculated in the run time, not compilation time, strlen is used to get the real size of the content of a string (string, char array, char pointer) until the '\0', not the real size of memory allocation. Most of the compiler will calculate the result of sizeof in the compilation time, no matter the parameter is type or variable, that is why sizeof(x) can be used to decide the dimension of an array:

char str[20]="0123456789"; 
int a=strlen(str); //a=10; 
int b=sizeof(str); //while b=20; 

7) If the parameter of sizeof is a type, then parentheses are mandatory, while if the parameter is a variable, parentheses are optional, because sizeof is an operator not a function;

8) When you use a structured type or variable as a parameter, sizeof will return its real size, when you use a static array, sizeof will return the array size. But sizeof operator cannot return the size of an array which is created dynamically or externally. Because sizeof is a compilation time operator.

Here is an example of sizeof and strlen:

#include <iostream>
#include <cstdlib>
#include <string>
#include <cstring>

short f1 ()
{
  return 100;
}

int f2 ()
{
  return 1000;
}

int main()
{
  char* char_star = "0123456789";
  // char_star is a char pointer, sizeof will return the pointer size allocated in memory: depends on your machine
  std::cout << "sizeof(char_star):" << sizeof(char_star) << std::endl;
  // *char_star is the first element of the string, it is a char, sizeof will return the char size allocated in memory: depends on your machine, normally is 1
  std::cout << "sizeof(*char_star):" << sizeof(*char_star) << std::endl;
  // char_star is a char pointer, strlen will return the real size of the string until '\0': 10
  std::cout << "strlen(char_star):" << strlen(char_star) << std::endl;
  std::cout << std::endl;

  char char_array[] = "0123456789";
  // char_array is a char array, sizeof will return the array size allocated in memory, with a '\0' at the end: 10 + 1
  std::cout << "sizeof(char_array):" << sizeof(char_array) << std::endl;
  // *char_array is the first element of the array, it is a char, sizeof will return the char size allocated in memory: depends on your machine, normally is 1
  std::cout << "sizeof(*char_array):" << sizeof(*char_array) << std::endl;
  // char_array is a char array, strlen will return the real size of the string until '\0': 10
  std::cout << "strlen(char_array):" << strlen(char_array) << std::endl;
  std::cout << std::endl;

  char_array_fixed[100] = "0123456789";
  // char_array_fixed is a char array with fixed size, sizeof will return the array size allocated in memory: 100
  std::cout << "sizeof(char_array_fixed):" << sizeof(char_array_fixed) << std::endl;
  // *char_array_fixed is the first element of the array, it is a char, sizeof will return the char size allocated in memory: depends on your machine, normally is 1
  std::cout << "sizeof(*char_array_fixed):" << sizeof(*char_array_fixed) << std::endl;
  // *char_array_fixed is a char array with fixed size, strlen will return the real content size of the string until '\0': 10
  std::cout << "strlen(char_array_fixed):" << strlen(char_array_fixed) << std::endl;
  std::cout << std::endl;

  int int_array[100] = {0,1,2,3,4,5,6,7,8,9};
  // int_array is a int array with fixed size, sizeof will return the array size allocated in memory: 100
  std::cout << "sizeof(int_array):" << sizeof(int_array) << std::endl;
  // *int_array is the first element of the array, it is an int, sizeof will return the int size allocated in memory: depends on your machine, normally is 4
  std::cout << "sizeof(*int_array):" << sizeof(*int_array) << std::endl;
  // int_array is a int array with fixed size, strlen will throw exception 
  //std::cout << "strlen(int_array):" << strlen(int_array) << std::endl;
  std::cout << std::endl;

  char char_array2[] = {'a', 'b', '3'};
  // char_array2 is a char array, sizeof will return the array size allocated in memory: 3
  std::cout << "sizeof(char_array2):" << sizeof(char_array2) << std::endl;
  // *char_array2 is the first element of the array, it is a char, sizeof will return the char size allocated in memory: depends on your machine, normally is 1
  std::cout << "sizeof(*char_array2):" << sizeof(*char_array2) << std::endl;
  // *char_array2 is a char array, strlen will return the real content size of the string until '\0': 3
  std::cout << "strlen(char_array2):" << strlen(char_array2) << std::endl;
  std::cout << std::endl;

  char char_array3[] = {"abc"};
  // char_array3 is a char array, sizeof will return the array size allocated in memory, with a '\0' at the end : 3 + 1
  std::cout << "sizeof(char_array3):" << sizeof(char_array3) << std::endl;
  // *char_array3 is the first element of the array, it is a char, sizeof will return the char size allocated in memory: depends on your machine, normally is 1
  std::cout << "sizeof(*char_array3):" << sizeof(*char_array3) << std::endl;
  // *char_array3 is a char array, strlen will return the real content size of the string until '\0': 3
  std::cout << "strlen(char_array3):" << strlen(char_array3) << std::endl;
  std::cout << std::endl;

  std::string str = {'a', 'b', '3', '\0', 'X'};
  // str is a string, sizeof will return the string size allocated in memory (string is a wrapper, can be considered as a special structure with a pointer to the real content): depends on your machine, normally is 32
  std::cout << "str:" << str << std::endl;
  std::cout << "sizeof(str):" << sizeof(str) << std::endl;
  // *str means nothing, sizeof will throw exeption
  //std::cout << "sizeof(*str):" << sizeof(*str) << std::endl;
  // str is a string, strlen will return the real content size of the string until '\0': 3
  std::cout << "strlen(str):" << strlen(str.c_str()) << std::endl;
  std::cout << std::endl;

  // sizeof is an operation, if the parameter is a type, parentheses are mandatory
  std::cout << "sizof(int):" << sizeof(int) << std::endl;
  // sizeof is an operation, if the parameter is a variable, parentheses are optional
  std::cout << "sizof char_star:" << sizeof char_star << std::endl;
  std::cout << "sizof char_array:" << sizeof char_array << std::endl;
  // sizeof is an operation, can take a function as parameter
  std::cout << "sizeof(f()): " << sizeof(f1()) << std::endl;
  std::cout << "sizeof(f()): " << sizeof(f2()) << std::endl;
}

Upvotes: 0

pb2q
pb2q

Reputation: 59637

As for the result from strlen, in your case you have an uninitialized char array, and so strlen only happens to yield 7: there must be a null character at array element 8, but this code could give different results for strlen every time.

Always initialize strings, it's easy enough with an array: char str[15] = {0};

sizeof is an operator used to get the size of a variable or a data type, or the number of bytes occupied by an array, not the length of a C string; don't expect strlen and strcpy to be interchangeable, or even comparable in any useful way.

For instance:

int main()
{
    char str[15] = "only 13 chars";

    cout << "strlen: " << strlen(str) << endl;
    cout << "sizeof: " << sizeof(str) << endl;
}

The output is:

strlen: 13
sizeof: 15

Upvotes: 1

CB Bailey
CB Bailey

Reputation: 792847

Your code has undefined behavior because you are reading the uninitialized values of your array with strlen. If you want a determinate result from strlen you must initialize (or assign to) your array.

E.g.

char ch[15] = "Hello, world!";

or

char ch[15] = {};

sizeof will give the size of its operand, as the size of char is one by definition the size of a char[15] will always be 15.

strlen gives the length of a null terminated string which is the offset of the first char with value 0 in a given char array. For a call to strlen to be valid, the argument to must actually point to a null terminated string.

Upvotes: 6

Pavan Manjunath
Pavan Manjunath

Reputation: 28545

ch is a local variable and local variables are not initialized. So your assumption that it is an empty string is not correct. Its filled with junk. It was just a co-incidence that a \0 character was found after 7 junk characters and hence strlen returned 7.

You can do something like these to ensure an empty string-

char ch[15]={0};
ch[0]='\0`;
strcpy(ch,"");

Here's a similar thread for more reading

Variable initialization in C++

Upvotes: 5

ForEveR
ForEveR

Reputation: 55897

Returns the length of str.

The length of a C string is determined by the terminating null-character: A C string is as long as the amount of characters between the beginning of the string and the terminating null character.

sizeof returns number of bytes (15). Your array is filled by garbage, so, strlen can returns any number. Correct example is

int main()
{
    char ch[15] = {0};
    cout<<strlen(ch)<<endl; //0
    cout<<sizeof(ch)<<endl; //15
    return 0;
}

Upvotes: 0

Kiril Kirov
Kiril Kirov

Reputation: 38173

The problem is in

strlen(ch);

strlen counts the number of chars, untill hitting the \0 symbol. Here, ch is non-initialized, so strlen could return anything.

Upvotes: 2

Related Questions