Using sizeof() on an array passed to a function
Array in C always passed by reference. Thats why you are getting pointer size each time, not actual size.
To work with array in C as an argument, you should pass size of array with array.
I modified your program to working condition:
typedef unsigned char BYTE;
void checkArraySize(BYTE data[], int sizeOfArray)
{
int internalSize = sizeOfArray;
printf("%d", internalSize );
}
void main(void)
{
BYTE data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
int externalSize = sizeof(data)/sizeof(BYTE); //it would return number of elements in array
checkArraySize(data, externalSize);
}
passed by reference means only address of first element of array is sent. If you change anything even inside function checkArraySize, this change would be reflected to original array too. Check modified above example.
typedef unsigned char BYTE;
void checkArraySize(BYTE data[])
{
int internalSize = sizeof(data);
printf("%d\n", internalSize );
data[3]= 0x02; //internalSize is reported as 4
}
void main(void)
{
BYTE data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
int externalSize = sizeof(data); //externalSize is reported as 8
printf("Value before calling function: 0x%x\n",data[3]);
checkArraySize(data);
printf("Value after calling function: 0x%x\n",data[3]);
}
output would be:
Value before calling function: 0x4
4
Value after calling function: 0x2
Using sizeof on arrays passed as parameters
What causes this inconsistency?
The name of the array decays as an pointer to its first element.
When you pass an array to an function, this decaying takes place and hence the expression passed to sizeof
is a pointer thus returning pointer size.
However, an array passed to sizeof
always returns size of the array because there is no decaying to an pointer in this case.
What is the best way of getting the size of an array when it is passed as a parameter?
Don't pass them by value, pass them by reference or
Pass size as an separate argument to the function.
Sizeof array passed as parameter of function
In most cases the size of a pointer is 8 bytes. In your system that is the size of the pointer.
Note that the size of the pointer, and you probably know this, is not the size of the object it points or the size of the type of object.
The size of a pointer depends on several factors, like the CPU architecture, compiler or Operating System.
The way it usually works is if the system is 16-bit, the of size pointers is 2 bytes, if the system is 32-bit, the size is 4 bytes, if it is 64-bit, it's 8 bytes.
Find the Size of integer array received as an argument to a function in c
You cannot do it that way. When you pass an array to a function, it decays into a pointer to the first element, at which point knowledge of its size is lost.
If you want to know the size of an array passed to the function, you need to work it out before decay and pass that information with the array, something like:
void function (size_t sz, int *arr) { ... }
:
{
int x[20];
function (sizeof(x)/sizeof(*x), x);
}
Weird behavior of sizeof for arrays passed as parameters
I never saw that syntax before in C++ but maybe you meant
void foo(const char data[10])
Anyway, in C++ arrays decay to pointers when passed to a function. So the function has no way of knowing how big the passed arrays are. In that sense, what I wrote above is completely equivalent to:
void foo(const char data[])
There is also a C FAQ about this subject.
Why isn't the size of an array parameter the same as within main?
An array-type is implicitly converted into pointer type when you pass it in to a function.
So,
void PrintSize(int p_someArray[10]) {
printf("%zu\n", sizeof(p_someArray));
}
and
void PrintSize(int *p_someArray) {
printf("%zu\n", sizeof(p_someArray));
}
are equivalent. So what you get is the value of sizeof(int*)
C sizeof a passed array
There is no magic solution. C is not a reflective language. Objects don't automatically know what they are.
But you have many choices:
- Obviously, add a parameter
- Wrap the call in a macro and automatically add a parameter
- Use a more complex object. Define a structure which contains the dynamic array and also the size of the array. Then, pass the address of the structure.
Why does a C-Array have a wrong sizeof() value when it's passed to a function?
When you pass an array into a function in C, the array decays into a pointer to its first element. When you use sizeof
on the parameter, you are taking the size of the pointer, not the array itself.
If you need the function to know the size of the array, you should pass it as a separate parameter:
void test(int arr[], size_t elems) {
/* ... */
}
int main(int argc, const char * argv[]) {
int point[3] = {50, 30, 12};
/* ... */
test(point, sizeof(point)/sizeof(point[0]));
/* ... */
}
Also note that, for a similar reason (taking the sizeof
a pointer), the sizeof(point)/sizeof(point[0])
trick doesn't work for a dynamically allocated array, only an array allocated on the stack.
Can the C++ Array class be passed as a parameter with variable size?
I am aware that a regular, built-in array can be passed in to a function with variable sizes.
No, it can't. It can only be passed in by-pointer or by-reference. In the case of by-pointer, all size information is lost. In the case of by-reference, the size has to be stated explicitly in the parameter itself as part of its type, thus you can't pass separate arrays of different sizes to the same function.
However, is there a good technique to be able to write a single function that takes an array class object reference, but the size can be variable?
Yes, use a template for the size, eg:
template<typename T, size_t N>
void doSomething(T (&arr)[N])
{
// use arr up to N elements as needed...
}
int arr1[5];
doSomething(arr1);
char arr2[10];
doSomething(arr2);
...
UPDATE: in the case of std::array
, the template approach still works, eg:
template<typename T, size_t N>
void doSomething(std::array<T, N> &arr) {
// use arr up to N elements as needed...
}
std::array<int, 5> arr1;
doSomething(arr1);
std::array<char, 10> arr2;
doSomething(arr2);
...
Related Topics
Are Child Processes Created with Fork() Automatically Killed When the Parent Is Killed
Linking a Shared Library with Another Shared Lib in Linux
Are Inner Classes in C++ Automatically Friends
C++ Function Pointer (Class Member) to Non-Static Member Function
Passing Arguments to Std::Async by Reference Fails
Serial Comm Using Writefile/Readfile
C++11 Inheriting Constructors and Access Modifiers
Are Memory Leaks "Undefined Behavior" Class Problem in C++
How to Embed a File into an Executable
What's This C++ Syntax That Puts a Brace-Surrounded Block Where an Expression Is Expected
About Binding a Const Reference to a Sub-Object of a Temporary
#Define Nominmax Using Std::Min/Max