Char array sizeof() method [duplicate] - c

This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
Closed 5 years ago.
Complete example:
#include <stdio.h>
void test(int arr[]) {
int arrSize = (int)(sizeof(arr) / sizeof(arr[0]));
printf("%d\n", arrSize); // 2 (wrong?!)
}
int main (int argc, const char * argv[]) {
int point[3] = {50, 30, 12};
int arrSize = (int)(sizeof(point) / sizeof(point[0]));
printf("%d\n", arrSize); // 3 (correct :-) )
test(point);
return 0;
}
Before passing it to a function, sizeof gives me the correct value. Doing the exact same thing on the exact same array in the function gives weird results. There's one element missing. Why?

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.

Because array is decayed to a pointer when passed as function argument, so sizeof gives you 4 and 8 for 32- and 64-bit platforms respectively.

Also, it's important to understand that sizeof is evaluated at compile time. Since that's the case, it doesn't make sense to expect different output in test() depending on what was passed in. The sizeof calculation was done when the function was compiled.

Because, when it's passed, only the pointer to array is actually being passed.
Your question is also answered at The C Programming FAQ. Question 6.21.

Because in C, C++, and Objective-C, functions cannot actually have array parameters. They only can have parameters that look like array parameters, but they aren't. In your example,
void test(int arr[])
the compiler sees "there is a parameter that looks like an array of int", and it replaces that parameter with a "pointer to int". So the function that you wrote is absolutely, one hundred percent, identical to
void test (int* arr)
Therefore, inside the function sizeof (arr) will give you the size of a "pointer to int".

Because sizeof() does NOT tell you the size of an array in C. It does something completely different.
sizeof C++ reference

Related

How to know how many elements there are in a pointer array? [duplicate]

This question already has answers here:
In C how to get number of items in array of pointers to char strings
(5 answers)
Closed 4 years ago.
void print(char *arch[], int num){
int i;
for(i=0; i<8; i++)
printf("%s\n", *(arch+i));
}
In this case I knew that arch was formed by 8 elements, but if I didn't know how can I know it? Is there a way?
Since arrays decay to pointers to their first element when passed as arguments to a function, length information is lost as well.
For example:
void bar()
{
int data[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printf("%zu\n", sizeof data); // output: 10 * sizeof(int)
foo(data);
}
void foo(int *arg)
{
printf("%zu\n", sizeof arg) // output: sizeof(int *)
}
This is why strings are null-terminated in C: so that when pointers to strings (or arrays decayed to pointers) are passed to string-handling functions, their length can still be determined by incrementing to the null-pointer and keeping count.
There is no way of knowing the length of an array given only a pointer to the array without one of:
A "length" parameter
A sentinel value indicating the end of the array (such as the null-terminator for strings)
There is no way you can know the size of array passed to function.
As array decays to pointer to first element.
Compiler will treat.
void print(char *arch[], int num)
as
void print(char **arch, int num)
Thus when you do
sizeof(arch); //It is size of pointer.
Solution:
You can pass size of array additional to function as parameter.
Have known value at the end of the array and loop until you find the expected value.

How does this function work without using any pointers? [duplicate]

This question already has answers here:
What is array to pointer decay?
(11 answers)
In C, are arrays pointers or used as pointers?
(6 answers)
Closed 4 years ago.
I'm attempting to learn C and going through the K&R book. Many examples online seem to use pointers to return a value from a function. I would think then that the same would be used for this K & R function:
/*
Reverse a string in place
*/
void reverse(char s[])
{
int c, i, j;
for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
int main()
{
char s[] = "HELLO";
reverse(s);
printf("%s", s);
return (0);
}
I would think that the string would NOT be reversed in this situation. Yet it prints the char array backwards as originally intended by the author.
How does it do that? I don't completely understand pointers yet but I was thinking it would be like reverse(&s) and then void reverse(char *s[]) {...}
Arrays, when passed as arguments to functions, decay to a pointer to their first element. Hence when you pass an any type of array (including a string) into a function, you are effectively passing it by reference and any modifications made to the array within the function will be reflected in the calling code as well, after the function call.
Examine the output of this code to enrich your understanding of pointers and arrays:
#include <stdio.h>
#include <stdlib.h>
void foo(int *arg, size_t len)
{
size_t i;
printf("sizeof arg is %zu\n", sizeof arg);
for(i = 0; i < len; i++)
{
printf("arg[%zu] = %d\n", i, arg[i]);
}
printf("arg's address is %p\n", (void *) arg);
}
int main()
{
int array[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
printf("sizeof array is %zu\n", sizeof array);
printf("array begins at %p in memory\n", (void *) array);
foo(array, 10);
return 0;
}
Since no copy of the string is made anywhere the original string must be modified by the array assignments in reverse. Changing void reverse(char s[]) to void reverse(char *s) would change nothing. An array of unknown size behaves just like a pointer to the array's first element.
I also learned C from K&R, it's one of the best books out there, although after reading it, get a book that covers C99 and C11.
If you look at section 5.3 in the book
5.3 Pointers and Arrays
They write:
When an array name is passed to a function, what is passed is the
location of the initial element. Within the called function, this
argument is a local variable, and so an array name parameter is a
pointer, that is, a variable containing an address.
So although arrays and pointers are different, when you pass an array to a function it does not pass the array, but a pointer to the first element.
some differences:
There is one difference between an array name and a pointer that must
be kept in mind. A pointer is a variable, so pa=a and pa++ are legal.
But an array name is not a variable; constructions like a=pa and a++
are illegal.
One thing to keep in mind about K&R book when you read it. They mention something once, and 50 pages later they use it, unless you remember it, it will look like it came out of nowhere. They don't repeat themselves much in the book.
The array will implicitly be converted to a pointer to the first element of the array when passed as an argument to a function.
That is why the the elements of the original array are modified and not a copy of it since no copy of the array is made; only the address of the first element.

c sizeof function of an array in a function is always four bytes despite the number of array elements [duplicate]

This question already has answers here:
"sizeof" to know the size of an array doesn't work in a function in C [duplicate]
(2 answers)
Closed 6 years ago.
When I print the (size of the array/size of the the first element), I get the right answer, but when I do the same thing in the function, I get the size of the array to be four and the size of the first element of the array to be four hence the division is always one.
#include<stdio.h>
int sizer(int *);
int main()
{
int num;
printf("Please an index: ");
scanf("%d",&num);
int array[num];
int size = sizer(array); //function to calculate array length
/*answer is always 4*/
printf("%d\n", size);
/*answer is correct*/
printf("%d\n", sizeof(array) / sizeof(array[0]));
return 0;
}
/*function to calculate array length*/
int sizer(int *array)
{
return sizeof(array) / sizeof(array[0]);
}
sizeof is not a function called at runtime, even though it looks like one. It is a feature of the compiler. It looks at a data object and replaces the sizeof() expression with a constant.
int arr[10];
int size = sizeof(arr)/sizeof(int);
This works because the compielr can see how big arr is. arr is a statically sized array here. Both sizeof expressions are replaced with the appropriate values.
int arr[10];
int size = sizer(arr);
....
int sizer(int array[]) {
return (sizeof(array)/sizeof(int));
}
This doesn't work. In sizer, array looks like an array but arrays passed in as parameters are actually just pointers to the array type. So sizeof(array) is equivalent to sizeof(int *)
scanf("%d",&num);
int arr[num];
int size1 = sizeof(arr)/sizeof(int);
int size2 = sizer(arr);
....
int sizer(int array[]) {
return (sizeof(array)/sizeof(int));
}
Here, size1 works but size2 doesn't. The creation of arr is actually allocated like this:
int arr_sizeof = sizeof(int)*num;
int *arr = alloca(arr_sizeof);
Then later on, sizeof(arr) is quietly replaced with arr_sizeof. But the compiler can only do this in the same scope that arr is created, because when arr is passed to sizer it's just converted to an int * again, so the size information is not carried over. sizer fails for thet same reason, arrays in function parameters are just passed along as simple pointers.
When you pass an array to a function you are really just passing a pointer to the first element, so in the body of sizer, the parameter array is just a pointer to int. Your function correctly returns sizeof(int*)/sizeof(int) (which is 2 rather than 4 on my machine), though this is probably not what you want. There really isn't any way for a function in C to compute the length of a passed array, which is why it is standard in C to pass the number of elements in an array as one of the parameters in any function which takes an array parameter.

Find the Size of integer array received as an argument to a function in c [duplicate]

This question already has answers here:
C sizeof a passed array [duplicate]
(7 answers)
Closed 8 years ago.
i would like to find the size of integer array passed as an argument to a function.
Here is my code
void getArraySize(int arr[]){
int len = (sizeof(arr)/sizeof(arr[0])
printf("Array Length:%d\n",len);
}
int main(){
int array[] = {1,2,3,4,5};
getArraySize(array);
return 0;
}
I am getting the following warning
sizeof on array function parameter will return
size of 'int *' instead of 'int []' [-Wsizeof-array-argument]
Please help so that i can find the length of integer array inside the function getArraySize
However am able to find the size of the array inside the main function.Since it is passed as a pointer, am not able to find the length from with in the function.
i do have an idea though.I could put this with in a try/catch block(C does not have try catch,Only jumpers which is OS dependent) and loop until i get a segmentation fault.
Is there any other way i could use to find the length of integer array inside the function
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);
}
When you pass an array to a function, its address is passed to the function as a pointer.
So void getArraySize(int arr[]) is equivalent to void getArraySize(int* arr).
As a result, sizeof(arr) yields sizeof(int*), which is probably not what you want.
You can safely use sizeof(arr)/sizeof(arr[0]) only within the scope of declaration of arr.
In your case, the scope of declaration of arr is function main.
The array decays to a pointer when passed.
So sizeof only works to find the length of the array if you apply it to the original array.
So you need to pass length of array as separate argument to function.
There is no way to determine the length inside the function. However you pass arr, sizeof(arr) will always return the pointer size. So the best way is to pass the number of elements as a separate argument.
sizeof only works to find the length of the array if you apply it to the original array.
int arr[5]; //real array. NOT a pointer
sizeof(arr); // :)
However, by the time the array decays into a pointer, sizeof will give the size of the pointer and not of the array.
void getArraySize(int arr[]){
sizeof(arr); // will give the pointer size
}
There is some reasoning as to why this would take place. How could we make things so that a C array also knows its length?
A first idea would be not having arrays decaying into pointers when they are passed to a function and continuing to keep the array length in the type system.
When you pass an array to a function it decays to pointer. So the sizeof function will return the size of int *. This is the warning that your compiler complining about-
sizeof on array function parameter will return size of 'int *' instead of 'int []'
As i suggested when you pass the array to the function you need to pass the Number of elements also-
getArraySize(array, 5); // 5 is the number of elements in array
Catch it by-
void getArraySize(int arr[], int element){
// your stuff
}
Else general way to calculate array size-
void getArraySize(int arr[], int len){
// your stuff
printf("Array Length:%d\n",len);
}
int main(){
int array[] = {1,2,3,4,5};
int len = (sizeof(arr)/sizeof(arr[0]); // will return the size of array
getArraySize(array, len);
return 0;
}

Why is the sizeof function returning to different values for the same array? [duplicate]

This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
Closed 9 years ago.
Consider this piece of code (or just copy/paste and run it):
#include <stdio.h>
int array[] = {1, 2, 3, 4, 5, 6, 7};
int my_put(int *array)
{
printf("Size of array %lu\n", sizeof(array));
return 0;
}
int main(int argc, char **argv)
{
printf("Size of array %lu\n", sizeof(array));
my_put(array);
return 0;
}
My question is: How come that the sizeof function returns two different values? Why is the size 28 in the main function and 8 in the my_put function?
Because in my_put(), array is an int * pointer, not an array. Your parameter shadows the global array variable. It might be clearer if you rewrite my_put to look like this:
int my_put(int *a)
{
printf("Size of array %zu\n", sizeof array);
printf("Size of a %zu\n", sizeof a);
return 0;
}
This new function doesn't confuse two variables named array. I also fixed it to use the z format specifier for size_t types.
Plenty more at the comp.lang.c FAQ, section 6, Arrays and Pointers, particularly Question 6.21 for your case.
In my_put name array is shadowed by your func's arg and its size is 8 (since it is a pointer). In main you get size of your 'real' array. That's all
In function my_put , array is pointer and its size is of the size of int *. Read C-FAQ 6.21.
Because its not the same "array". You have two arrays here -- the global variable "array" and the argument "array" to my_put. Now the second one is actually a pointer that points at the first one, but its a distinct variable with a different type (int pointer vs int array), so it has a different size.

Resources