Is there anything wrong with sizeof(array)/sizeof(array[0])?

匿名 (未验证) 提交于 2019-12-03 01:58:03

问题:

One of my colleagues has recently said that the above statement is not type safe and I should use something else as you need as much type safe structures as possible to reduce the amount of possible bugs.

Whilst I agree on being type safe, I'm a little confused as this is the type of code in question (only the contents and length of data[] is modified)

unsigned char data[] = {1,2,3,4,5}; int data_len = sizeof(data) / sizeof(data[0]);  

Where is the part that is not type safe?

Needless to say, other than the comment, the colleague will not explain further.

PS: This is used to copy initialisation data into a class from the constructor, no C++11 compiler exists here, so we can't use std::array or other fancy array initialisation. techniques.

回答1:

Maybe your colleague meant that using this expression with pointers will give an unexpected result. This mistake is made very often by beginners. For example

void f( unsigned char data[] ) {    int data_len = sizeof(data) / sizeof(data[0]);     //... }  //...  unsigned char data[] = {1,2,3,4,5}; f( data ); 

So in general case it would be more safely to use a template function instead of the expression. For example

template   inline size_t size( const T ( & )[N] ) {    return N; } 

Take into account that there is template structure std::extent in C++ 11 that can be used to get the size of a dimension.

For example

int a[2][4][6];  std::cout ::value ::value ::value 


回答2:

One possible problem is that if data is created on the heap with new, you won't get the length, instead some value related to the length of a pointer on the system you are on.

char* data = new char[5];  //sizeof(data) is dependent on system 


回答3:

sizeof data / sizeof *data is perfectly fine and typesafe. But you must be able to guaranted that:

  • You really feed it an array, not a pointer
  • Said array is not zero length
    • Up to C99 at least , int[0] would be a constraint violation and thus must be diagnosed. Many compilers allow it as an extension.
    • Up to C++13 at least, the same holds true for C++.

You can get a diagnostic if you didn't provide an array by using templates:

template  inline size_t elements_of(const T&[n]) {   return n; } 


回答4:

#include void fun(int arr[])   {   /* sizeof cannot be used here to get number  of elements in array*/   int arr_size = sizeof(arr)/sizeof(arr[0]); /* incorrect use of sizeof*/ }  int main() {   int arr[4] = {0, 0 ,0, 0};   fun(arr);     return 0; }  

In C, array parameters decay to pointers. So the expression sizeof(arr)/sizeof(arr[0]) becomes sizeof(int*)/sizeof(int) which results in 1 for IA32 machine.

Therefore, sizeof should not be used to get number of elements in such cases. A separate parameter for array size (or length) must be passed to fun(). So the corrected program for printing the numbers is:

#include void fun(int arr[], size_t arr_size)   {   int i;      for (i = 0; i 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!