I happened to ask myself a question about arrays in c++. Well, we all know that arrays are fixed collections of something, I say fixed because it is necessary to declare array length when defining arrays. Well, let's consider an example:
char myarray[10] = {'\0'};
int sz = sizeof(myarray); // It is supposed to be 10
Well, it is correct, 10 is the number returned by sizeof. This can be done by the compiler because he knows how much space it placed for that variable.
Now consider what happens in this situation:
void dosome(mystruct* arr) {
int elements = sizeof(arr)/sizeof(mystruct);
for (int i = 0; i < elements; i++) {
// Do something hoping no overflow will ever occur
}
}
Nice... but I suppose it can be overflow 开发者_高级运维prone. If I pass to this function an array I created in a "normal" way, everything should be fine:
mystruct array[20];
dosome(array);
No problem. But if I do this:
mystruct* array = (mystruct*)malloc(80*sizeof(mystruct));
dosome(array);
WHAT HAPPENS??????????????????? I would like to understand how sizeof behaves, this function is evaluated at compile time right??? ok, what happens when I use not an array, but something very cumbersome like a block of data like that one? furthermore, I could realloc it woth another call to malloc and ask to dosome to process that datablock again. Will it work? I could try it physically, but I would get some exact answer about the behavioir of sizeof.
Thank you.
it's wrong starting from the mystruct array[20]
example. Because the function receives a pointer type, and not an array type, it cannot deduce the number of elements in the array. you are actually getting the size of a mystruct*
when you perform sizeof(arr)
.
You can use templates to write functions which take arrays as parameters, but the suggested way in C++ is to use vector
s, if I am not wrong.
The "way" to receive arrays as parameters would be to write something like:
template <int N> void somefunction(int (&v)[N]);
EDIT corrected the function declaration. oops.
void dosome(mystruct* arr) {
int elements = sizeof(arr)/sizeof(mystruct);
for (int i = 0; i < elements; i++) {
// Do something hoping no overflow will ever occur
}
}
What type does arr have in this example? mystruct*
! And it's size is most likely 4 or 8. If you want to pass statically/automatically allocated arrays (not new'd) to functions preserving the size so that your trick works, pass by REFERENCE!
template <int N>
void dosome(mystruct (& arr) [N]) {
for (int i = 0; i < N; i++) {
// Do something . No overflow will occur
}
}
Also note this
int a[20];
sizof a; //equals to 20*sizeof(int)
int* b = new int [20];
sizeof b; //equals to sizeof pointer, most likely 4
sizeof is a compile-time operator. And here it computes only the size of a pointer.
精彩评论