This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Stack pointer difference for char pointer and array
To illustrate my question:
int main(void){
int myary[20];
int *myaryPtr;
myaryPtr = myary;
sizeof(myary); // Will it return 80? Correct?
sizeof(myaryPtr); // Will it return 4? Correct?
return 0;
}
First off, is my assumption correct?
And then assuming my assumption is correct, what is the detailed explanation? I understand that my 20 element array is 80 bytes, but isn't the name myary merely a pointer to the first element of the array? So shouldn't it also be 4?
Yes, your assumption is correct, assuming an int and a pointer are both 4 bytes long on your machine.
And no, arrays aren't pointers. The array name sometimes decays into a pointer in certain contexts, but they aren't the same thing. There is a whole section of the comp.lang.c FAQ dedicated to this common point of confusion.
The size of the array is not stored in memory in either case, whether you declare it as int myArr[20] or int* myArrPtr.
What happens is that sizeof() is replaced (by the compiler) with a constant value.
Therefore, because myArr was specified with a fixed size prior to compilation, the compiler knows just how big the amount of memory allocated is. With myArrPtr, you could dynamically allocate different array sizes, so only the size of the type is stored.
Related
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)
Sizeof array through function in C [duplicate]
(2 answers)
Closed 4 months ago.
#include <stdio.h>
int avg(int []);
void main(){
int average;
int marks[5]={10,15,20,30,45};
printf("%d\n",sizeof(marks)); // answer is 20(as expected)
avg(marks);
}
int avg(int marks[]){
int sum=0;
printf("%d\n",sizeof(marks)); // answer is 8(why???)
}
In this code, I was trying to print the sizeof the integer pointer marks. When I print the sizeof the marks inside the main method it gives 20 as the result as we expected. But the same object passes to the avg function and prints the sizeof marks it shows the result as 8. I couldn't understand why that was happening.
Can anyone please clarify this?
Any help would be appreciated.
In the C programming language, arrays "decay" into pointers when passed to functions.
This means that in the scope where an array is declared, sizeof will be able to tell you how many bytes it takes up, but once it is passed to another function, sizeof can only tell you the size of a pointer to the type of the array. Effectively, when an array is passed as a parameter, you lose all length-of-array related information. All that is preserved is the memory-address where the array starts, and its type, so in your case, sizeof marks in main() is equivalent to sizeof(int[5]) and sizeof marks in avg() is equivalent to sizeof(int*).
The consequences of this are that if you are going to be passing arrays of different lengths to a function, then you either have to send a separate length parameter, or give the function some way to infer the length of the array.
For instance, C strings are implemented as arrays of char, such that the last character of the array is the null-terminator byte, '\0'. This allows a function that expects a C-standard string parameter to keep reading byte after byte from the string without stopping until it finds the '\0', but this is controversial, as it is a rather significant source of bugs and security concerns, because if this assumption fails, and there is no '\0' at the end of the string, then the function could very well blindly access memory it has no business messing with.
If you need to pass an array pointer to a function and preserve its length, the best (or perhaps least controversial) solution is to pass the length along with the array, so int avg(int marks[],int numMarks); might be a function prototype that will serve your purposes. You could implement a system, where there is a value of int that is an invalid mark to be averaged, and use it to mark the end of the array, but this is likely a more difficult solution to implement safely.
It is size of the int*, which is 8 on your system.
This question already has answers here:
Newbie questions about malloc and sizeof
(8 answers)
Closed 7 years ago.
I am a newbie to C,
My Problem is the following code,
int Max[10],*New_Max;
int length=5;
New_Max=(int)malloc(sizeof(int)*length));
printf("sizeof(Max)=%d,sizeof(New_Max)=%d",sizeof(Max),sizeof(New_Max));`
Output:
sizeof(Max)=40,sizeof(New_Max)=4
I Expect sizeof(New_Max) to be 20, but it prints as 4.
Can anyone explain the reason for it.
The following line allocates memory to what New_Max is pointing.
New_Max=(int)malloc(sizeof(int)*length));
And, the following line grabs the info about what a pointer size is :
sizeof(New_Max)
So, the size of what pointer is pointing and its own size are two different things. That's why you are getting size of New_Max to be 4.
You are making wrong assumption, that sizeof behaves in the same way for both types of memory allocation. There is fundamental difference between array and pointer and how it relates to sizeof. If you provide it with array, like here:
int Max[10];
size_t size = sizeof(Max);
then you will get overall size, that is number of elements multiplied by size of each element, that is:
10 * sizeof(Max[0])
On the other hand, for pointers, it results into size of pointer itself, not taking any elements into account, thus what you get is just sizeof(int *). It does not matter if it points to NULL or some array object, the size would be the same.
Note that, the proper format specifier for sizeof is %zu, not the %d.
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 8 years ago.
I have the following code in C:
int array[5] = {0,1,2,3,4};
int * p = &array[0];
how to use the pointer p to get the size of this array p point to?
Sorry, this is actually impossible. The size of an array is not saved anywhere. You'll have to do it yourself.
It can't be done just from a pointer. The pointer is literally the address in memory of the first element of the array. The array size is not automatically associated with this pointer. You must keep track of the size yourself.
One workaround you can use is to reserve a special value for your array elements, say -1. If you can arrange for your last element to always have this value, then you can always find the end of the array by searching through it for that value. This is why strings have a null terminator, so strlen() and family can find the end of the string.
The short answer: In C, an array size cannot be retrieved from a pointer. The size must be passed separately.
The slightly-less-short answer: In C, a pointer is just an address to a spot in memory. The pointer does not even guarantee that there is a valid array or variable here; it is just a descriptor of a memory location.
In fact, in C, the concept of an array "size" is somewhat loose. A certain amount of consecutive memory can be allocated, but there is no checking as to if a pointer leaves this memory.
For example:
int a[] = {1, 2, 3};
int b = a[7];
will compile properly. C does not have any bounds checking!
you can not know the size of array using pointer to it. you cant determine since there is no way to know the end of array or to know that we reached the last element of array.
So, after reading 5 previous answers, here a better one:
a) You cannot get the element count of an array using a pointer.
Common workaround are:
Using a sentinel value (see C-String aka asciiz)
Passing the length separately. (see counted strings using mem*())
Actually using a struct, resp. reserving element 0 (or -1) for a lenght value. (also see counted strings).
Just allocate a whopping big amount of memory you know will suffice and not bother with the actual length at all. Getting this wrong is fun and easy to do.
b) You can get the element count of an array using the array name:
struct foo[my_expr];
ìnt count = sizeof array / sizeof *array;
This question already has answers here:
Sizeof arrays and pointers
(5 answers)
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 9 years ago.
Sample code :
#include <stdlib.h>
#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *p;
p = arr;
printf("Total size calculating from array = %ld\n", sizeof(arr));
printf("Total size calculating from pointer = %ld \n",sizeof(p));
return 0;
}
Output :
Total size calculating from array = 20
Total size calculating from pointer = 8
My understanding so far was that you can assign the address of the array to a pointer of same data type and do all the operations on it without any problem. But sizeof is returning different values.
So i have few questions here :
Is assigning good practice or not?
What things gets changed when we assign?
why 8?
Is assigning good practice or not?
Yes, for example if you pass an array to a function it will decay into a pointer. Let's say you need to keep the original pointer but you also need another one to iterate through the array. You declare a separate pointer that points to the same address and use that to iterate through it.
What things gets changed when we assign?
The pointer points to an address, that's it (previously it could have pointed to another address or NULL), the assignee (in your case the array) is not modified. There is a big difference between an array and a pointer which is why you get different results for it. Pointers and arrays are only seemingly equivalent.
You can still use the pointer to access and modify the contents of the array, but the two are not the same (as illustrated by the result of sizeof).
why 8?
On 32 bit machines a pointer is normally 4 bytes big, on 64 it is 8. If you take the size of a local array, the sizeof will multiply the number of elements in the array by how big each element is. Five integers each four bytes big equals 20.
array size denotes the total size of the array which in this case are 5 integers. But a pointer to the array actually stores a memory address whose size depends on the system you are using. So they are different
sizeof(arr) is giving size of array which is 20 Bytes in your case.When you perform p = arr; it is actually assigning address of first array element(&arr[0]) to integer pointer p.So now sizeof(p) is giving size of integer pointer only.
Remember array and pointer are not same.Array name is address of its first element.An array may decay as pointer.
why 8?
sizeof operator gives total byte size for statically defined array while for pointers it gives pointer size which can be 8 bytes for 64 bit systems and 4 bytes for 32 bit systems.
Is assigning good practice or not?
Yes, because in C you do not have much choice but a better way is using references in C++.
What things gets changed when we assign?
Nothing changes, original data is preserved.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
length of array in function argument
How do I get the length of a dynamically allocated array in C?
I tried:
sizeof(ptr)
sizeof(ptr + 100)
and they didn't work.
You can't. You have to pass the length as a parameter to your function. The size of a pointer is the size of a variable containing an address, this is the reason of 4 ( 32 bit address space ) you found.
Since malloc just gives back a block of memory you could add extra information in the block telling how many elements are in the array, that is one way around if you cannot add an argument that tells the size of the array
e.g.
char* ptr = malloc( sizeof(double) * 10 + sizeof(char) );
*ptr++ = 10;
return (double*)ptr;
assuming you can read before the array in PHP, a language which I am not familiar with.
Here you see the dangers of C: a ptr just points to memory and has no way of knowing what supposed size is. You can just increment and increment and the OS might complain eventually, or you crash your program, or corrupt other ones. You should always specify the size, and check bounds yourself!
This is similar to Using pointer for crossing over all elements in INTEGER array
See my answer here