This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 6 years ago.
#include <stdio.h>
int a[3] = {1,2,3};
void cal(int* item){
printf("Length(inside) is %lu\n", sizeof(item)/sizeof(item[0]));
}
int main(){
printf("Length(outside) is %lu\n", sizeof(a)/sizeof(int));
cal(a);
}
The code above comes out with the result that
Length(outside) is 3
Length(inside) is 2
However, it is wrong, because both of them should be 3, what's wrong with my code?
First of all, you should be using %zu fomat specifier to print the result.
Secondly, when passed to a function as argument, array name decays to the pointer to the first element, so the sizeof(item) will not work as expected.
Basically what you're doing is sizeof (int *)/ sizeof (int) and in your environment, it is likely that a pointer occupies 8 bytes and an int takes 4, so you get this result.
This is because the array decays into a pointer when it is passed to a function.
So essentially what you are doing is
sizeof(int*)/sizeof(int);
What you can think is the difference between
int a[5];
sizeof(a)/sizeof(a[0]); //this works
and
int a[5];
int* p = a;
sizeof(p)/sizeof(p[0]);
Related
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.
This question already has answers here:
Is an array name a pointer?
(8 answers)
Closed 8 years ago.
Suppose an array int a[10].
Why we can't do a=a+1 ? but the same is valid with a pointer variable.
int *ptr = a;
ptr = a+1;
How are both scenarios seen practically?
Because array locations are constant.
You can't change the value of a, since that represents the starting address of the array. Moving it doesn't make any sense.
With int *ptr; your variable ptr is just a single pointer and can of course be set to point to anywhere you like.
There's no contradiction here. It's a little like with functions, the name of a function evaluates to its address (called "a function pointer") but you can't assign to that either.
Because Array name is constant pointer pointing to its first element.You cannot change the value of constant variables,i,e what the const keyword is used for.
int a[10]; //here a (array variable is Const i,e you Cannot a=a+1)
int* const p=&a[0]; //here Also Same,Now p is Const i,e you Cannot p=p+1.
But Here:
int* pp=&a[0];//Here pp=pp+1 will work, Because pp is not Const.
You can if the array is a function argument
#include <stdio.h>
int rval(int a[10]) {
a = a + 1;
return a[0];
}
int main(){
int a[10] = {0,1,2,3,4,5,6,7,8,9};
printf ("%d\n", rval(a));
return 0;
}
Program output
1
This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
Closed 8 years ago.
I'm working with some arrays in plain C99 and I need to know their size. Does anyone knows why this is happening:
int function(char* m){
return sizeof(m) / sizeof(m[0]);
}
int main(){
char p[100];
int s = sizeof(p) / sizeof(p[0]);
printf("Size main: %d\nSize function: %d\n",s,function(p));
return 0;
}
Output:
Size main: 100
Size function: 8
Thanks!
Arrays decay to pointers at the first chance they get, thus in function all you have is a pointer, which is 8 bytes in your case.
This is happening because sizeof(m) == sizeof(char*), which is 8 on your platform.
When you call function(p), p decays into a pointer and loses its size information.
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.
This question already has answers here:
Stack pointer difference for char pointer and array
(1 answer)
C pointers and arrays/ 'sizeof' operator [duplicate]
(2 answers)
Closed 9 years ago.
Hi i was doing this exercise and wanted to get the size of array after i pass the pointer to the array to the function:
But the sizeof() operator doesn't work on pointer but works on the array name. Why is it so?
Is this any way i could get the size of the array on the findPut function?
#include <stdio.h>
//global vars
int i,j;
//functions prototypes
void findPut(int *, int);
int main(void){
int ins=4;
int arr[10]={1,2,3,5,6,7,8};
printf("%d\n",sizeof(arr)); //gives 40
int *ap=arr;
printf("%d\n",sizeof(*ap)); //gives 4 instead of 40 why?? if ap and arr the same thing
findPut(ap, ins);
return 0;
}
//functions
void findPut(int *p, int n){
//vars
//getting size of array
int size= sizeof(*p);
//sizeof(int);
printf("%d\n",size); //gives 4 but expected 40????
}
When you dereference *p you get an int, so it returns 4 (which is the size of int on your platform).
Because, sizeof(*ap) means sizeof(arr[0]); since array is of type int, sizeof(int), since in your system configuration, int is of size 4 you got the result as 4.
You can try it your self by printing the value of *p, you will get the value of arr[0].
Let int *p be a pointer and int arr[10]
Please note that:
Arrays and Pointers are not equivalent.
sizeof operator is a compile time operator.
sizeof(arr), evaluates to 10*sizeof(int), that is 10*4=40 in your case.
When you dereference p (getting the value that p points to), it doesn't give you whole array, but one unit of
your array that is an int so, *p means arr[0]. sizeof(arr[0]) is
4 (in your case) that's obvious.
When you use sizeof(p), it will give you the size of the pointer in your machine.
In my machine it is 8.
main function's return type should be int always. It has to retport operating system the exit status of the program. If you use void it might return random garbage.
The example demonstrate the issue:
#include<stdio.h>
#include<stdlib.h>
int main(){
int *p=NULL;
int arr[10]={10,1,2,3,5,6,7,8,9,10};
p=arr;
printf("values: arr[0]=%d *p= %d\n\n",arr[0],*p);
printf("sizes : sizeof(arr[0])=%lu, sizeof(*p)= %lu sizeof(int)=%lu\n\n",sizeof(arr[0]),sizeof(*p),sizeof(int));
printf("Sizeof pointer p: %lu \n\n",sizeof(p));
printf("Sizeof arr: %lu \n\n",sizeof(arr));
printf("Pointing p to the first byte of 100 byte sequence\n\n");
p=malloc(100);
printf("Though p is pointing 100 byte block, sizeof(p)=%lu",sizeof(p));
return 0;
}
Essentially, sizeof evaluates the sizeof type but not the sizeof type it points to.
Thank you, i do appreciate your knowledge but is there any way i could
find the size of array inside another function( not the one where i
define the array).
You can't in my IMHO! You have to pass the size along with the array.
Example:
int main(){
int arr[10]={10,1,2,3,4,5};
printf("Length of array: %lu",findLength(arr,sizeof(arr)));
return 0;
}
size_t findLength(int *p,int size){
return size/sizeof(*p);
}
You have an int array and an int pointer:
int arr[10] = {1,2,3,5,6,7,8};
int* ap;
ap = arr;
In C, the expression arr is equivalent to &arr[0]. It stands to reason, then, that *ap is equivalent to arr[0], which is an int, which for your binary has a size of 4.
You also need to understand that arrays and pointers aren't the same thing. You may have been confused by the fact that arrays and pointers are often used interchangeably in the sense that a pointer can store the address of the beginning of an array (its first element, in other words) and navigate the consecutive addresses as if it had the actual array passed to it.