tags:

views:

2015

answers:

6

I declare a static char array, then I pass it to a function. How to get the no. of bytes in the array inside the function?

+7  A: 

You would have to pass it to the function. You can use sizeof() to get the size of an array.

const char foo[] = "foobar";

void doSomething( char *ptr, int length)
{

}


doSomething(foo, sizeof(foo));

This MSDN page has explains more about sizeof and has a bigger example.

Edit: * see j_random_hacker's answer for an intriguing technique using templates... *

Paul Dixon
Can I do it without passing?
Ron
No. See my answer below.
abelenky
Paul, your answer is correct for C, but in C++ you can define a function template that does "discover" the size of a static array.
j_random_hacker
Nice! will reference it..
Paul Dixon
You should divide the length through 8! sizeof() returns the number of bits - not bytes.
brainfck
@brainfck: ... no. See http://msdn.microsoft.com/en-us/library/0w557fh7(VS.80).aspx for confirmation.
int3
A: 

You can't. Arrays in C++ are pointers, and that is all you have: the pointer to the beginning of the array. If it happens to be a string, you can use strlen to measure its length. If its some other known format, you can calculate the length according to that format.

Consider this code:

static char str[] = "hello world";

foo(str);
bar(str);

void foo(char* str)
{
   // length of str is unknown
}

void bar(char str[])
{
  // length of str is still unknown
}

Regardless of if your function parameter is a char[] or a char*, you don't know the size.

I suggest passing the size in as a separate parameter.

abelenky
Your answer is correct for C, but in C++ you can define a function template that does "discover" the size of a static array.
j_random_hacker
A: 

One other option you have is creating a string class that manages the string. I'm sure someone out there has done this already. The most primitive version is a struct with a char * and the buffer length, where you have to manually manage the size whenever it changes. The other end of the spectrum is a fully implemented string class, with operator overloading and manupulation functions.

Then pass this class to your function and it already knows the size. It isn't really any different then passing it as a separate parameter; it simply is an easier way of managing strings if they're all different lengths.

lc
You're on the right track, but why invent your own string class when std::string already exists and does exactly what is needed?
j_random_hacker
Also true. It's been a while...
lc
+9  A: 

Use a function template instead that has a non-type template parameter:

template <size_t N>
void func(char (&a)[N]) {
    for (int i = 0; i < N; ++i) {
        cout << "a[" << i << "] = " << a[i] << endl;   // Or whatever you want to do
    }
}

To call:

char myArray[500];        // Or "static char myArray[500]", if you want
func(myArray);

A new copy of this function will be instantiated for each distinct size of array that it is called with, so if you call it with many different-sized arrays, you'll get some code bloat. But that's not likely to be the case.

j_random_hacker
What a great idea! thanks.
Oren S
Nice!template<typename T, size_t N>size_t elments_of_array( T (}
fmuecke
+5  A: 

No. Don't use arrays. Use a vector instead. These days there is almost no excuse for using arrays because they are unsafe. AFAIK, they are one of the main reasons for software problems because it's so easy to accidently overrun the end of the array.

Using a vector, you don't have to worry any more about buffer overruns. And your function can easily find out the size of the vecor.

#include <vector>
vector<char> myVector;

void DoSomething(vector<char> &v)
{
    int sizeOfVector = v.size();
}

Hugo

Rocketmagnet
A: 

int array_size = sizeof(Array) / sizeof(Array[0]);

this is very error prone, as someone might replace the array with a pointer, causing the size to be incorrect.I would use j_random_hacker's method as it refuses to compile in these situations.
Oren S