sizeof(array)/ sizeof(array [0])有什么问题吗?

时间:2014-03-31 21:25:27

标签: c++ arrays type-safety

我的一位同事最近说上述声明不是类型安全的,我应该使用其他东西,因为你需要尽可能多的类型安全结构来减少可能的错误数量。

虽然我同意类型安全,但我有点困惑,因为这是有问题的代码类型(只修改了数据[]的内容和长度)

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

哪种部件不安全?

毋庸置疑,除了评论之外,同事不会进一步解释。

PS:这用于将初始化数据复制到构造函数的类中,此处不存在C ++ 11编译器,因此我们不能使用std :: array或其他花式数组初始化。技术。

4 个答案:

答案 0 :(得分:5)

也许你的同事意味着使用带有指针的表达式会产生意想不到的结果。初学者经常犯这个错误。例如

void f( unsigned char data[] )
{
   int data_len = sizeof(data) / sizeof(data[0]); 
   //...
}

//...

unsigned char data[] = {1,2,3,4,5};
f( data );

因此,在一般情况下,使用模板函数而不是表达式会更安全。例如

template <class T, size_t N>

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

考虑到C ++ 11中有模板结构std::extent,可用于获取维度的大小。

例如

int a[2][4][6];

std::cout << std::extent<decltype( a )>::value << std::endl;
std::cout << std::extent<decltype( a ), 1>::value << std::endl;
std::cout << std::extent<decltype( a ), 2>::value << std::endl;

答案 1 :(得分:2)

一个可能的问题是,如果在堆上使用new创建数据,则不会获得长度,而是与您所在系统上的指针长度相关的某些值。

char* data = new char[5];

//sizeof(data) is dependent on system

答案 2 :(得分:1)

sizeof data / sizeof *data非常好并且类型安全。但你必须能够保证:

  • 你真的给它一个数组,而不是一个指针
  • 所述数组不是零长度
    • 至少达到C99,int [0]将违反约束条件,因此必须进行诊断。许多编译器都允许它作为扩展。
    • 至少达到C ++ 13,C ++也是如此。

如果您未使用模板提供阵列,则可以获得诊断信息:

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

答案 3 :(得分:-1)

#include<stdio.h>
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;
} 

在C中,数组参数衰减为指针。因此表达式sizeof(arr)/sizeof(arr[0])变为sizeof(int*)/sizeof(int),导致IA32机器为1。

因此,在这种情况下,不应使用sizeof来获取元素数量。必须将数组大小(或长度)的单独参数传递给fun()。因此,用于打印数字的更正程序是:

#include<stdio.h>
void fun(int arr[], size_t arr_size)  
{
  int i;   
  for (i = 0; i < arr_size; i++) 
  {  
    arr[i] = i;  
  }
}

int main()
{
  int i;  
  int arr[4] = {0, 0 ,0, 0};
  fun(arr, sizeof arr / sizeof arr[0]);

  for(i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
    printf(" %d ", arr[i]);

  getchar();  
  return 0;
}