3

I have an character array of the form

char x[]='asdasdadsadasdas';
int p = sizeof(x)/sizeof(*x)

gives me correct result but when I pass this as an argument in another function like

void X(char* a)

int i = sizeof(a)/sizeof(*a)

and I call it

X(x)

p and i are not equal.How is it possible ?

saurabh
  • 293
  • 2
  • 7
  • 19
  • Are you really sure that compiles? – Deduplicator Dec 24 '14 at 14:50
  • Why an array of `char`? You'll probably have an easier time with `std::string` or `std::vector`, depending on what you're actually trying to do. – OJFord Dec 24 '14 at 14:52
  • @Deduplicator yeah it compiles perfectly – saurabh Dec 24 '14 at 15:02
  • `char x[]='asdasdadsadasdas';` that should be an error, initializing a char-array of unknown length with a multi-character-constant. You are using `-Wall -Wextra -pedantic` and treating all warnings as errors? – Deduplicator Dec 24 '14 at 15:18

3 Answers3

3

When the char array gets passed to a function accepting a char*, the array is said to 'decay' to a pointer. This conversion is automatic, and the length information which was previously statically available to the compiler is lost.

Possible solutions are:

  • Pass the size of the array as an additional parameter.
  • Make the char-Array 0-terminated (i.e., a string literal) and use strlen. This is the common ways of operating on strings in C and C++. However, this introduces runtime cost which is not strictly necessary. However it provides some convenience (same API for statically and dynamically sized strings) and error resilience (the length is always correct).
  • Use templates to capture the length of the array. This is explained here..
Community
  • 1
  • 1
Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
2
void X(char* a)

    int i = sizeof(a)/sizeof(*a)

Here, a is a pointer and *a is a char. So sizeof(a) won't return the size of the array, but the size of the pointer to the first element in the array.

In order to find the length of the string (which isn't the same as "the size of the array"), you have a few options.

One, don't use a char* at all, but a std::string (may create a temporary):

void X (const std::string& s)
{
  size_t i = s.length();
}

Two, scan the string for the null-terminator (linear complexity):

void X (const char* p)
{
  size_t i = strlen (p);
}

Three, use a template (needlessly complex code):

template <size_t N> void X (const char (&arr)[N])
{
  size_t i = N;
}

Each of the above has it's own set of cons. But this is all best avoided if you take a broader look at your program and see where you can make improvements. Here's one that stands out to me:

char x[]='asdasdadsadasdas';

C-style arrays present their own problems and are best avoided altogether. Instead of using a C-style array, use a tool from the StdLib designed for just this problem:

std::string x = "asdasdadsadasdas";
John Dibling
  • 99,718
  • 31
  • 186
  • 324
1
sizeof(char *) 

Gives you the size of a pointer. Eight bytes on my system.

char x[] = "fred"; 
sizeof(x);

Returns 5. The size of the string with the null termination.

void x(char * c) { 
sizeof (*c); 
} 

Returns the size of a a char.

This is true no matter what the length or original type of the array is passed to void x(). Note that sizeof() is evaluated at compile time. At compile time the compiler cannot normally know what length of array it's been passed. For a run-time evaluation of string length, as said above, use strlen if you actually want the strings length in characters. (Or a template - but that's probably a more unusual solution).

JCx
  • 2,689
  • 22
  • 32