関数の引数に配列を使うときの注意 | 備忘のためのメモ

関数の引数に配列を使うときの注意

整数値をバイトデータ列に変換するプログラム
-----------------------------------------------------------------------------------
int conv_val2array(unsigned int val, unsigned char array[])
{
 unsigned int i, work;
 unsigned int array_len;
 unsigned long long max_val;

 array_len=sizeof(array)/sizeof(array[0]);
 max_val=(1<<(8*array_len))-1;
 if(val>max_val){
  return 1;
 }else{
  work=val;
  for(i=1, i<=array_len, i++){
   array[array_len-1]=work%0x100;
   work=work/0x100;
   }
  return 0;
 }
}

int main(int argc, char *argv[])
{
 unsigned int i, a=0x123456;
 unsigned char data[3];
 conv_val2array(a, data);
for(i=0; i<3; i++) printf("data[%d]=%x ", i, data[i]);
 printf("\n"");
 return 0;
}
-----------------------------------------------------------------------------

のはずだったのに、全然言うこと聞いてくれないこの子

原因1: 関数の引数で配列を渡してしまうと、sizeof演算子で配列の要素数は求まらない。
得られるサイズはポインタ変数のサイズになる。

[対策]
要素数については呼び出し元で取得。そして引数として要素数に関する情報も渡す。

原因2:キャストに注意

[対策]
max_val=((unsigned long long)1<<(8*(unsigned long long)array_len))-1;

原因3:負の数のビットシフトに注意


◆修正版
-----------------------------------------------------------------------------------
int conv_val2array(unsigned int val, unsigned char *array, unsigned int array_len)
{
unsigned int i, work;
unsigned long long max_val;

max_val=((unsigned long long)1<<(8*(unsigned long long)array_len))-1;
if(val>max_val){
  return 1;
}else{
  work=val;
  for(i=1; i<=array_len; i++){
  array[array_len-i]=work%0x100;
   work=work>>8;
   }
  return 0;
 }
}

int main(int argc, char *argv[])
{
 unsigned int i, a=0x123456;
 unsigned char data[3];
 conv_val2array(a, data, 3);
 for(i=0; i<3; i++) printf("data[%d]=%x ", i, data[i]);
 printf("\n"");
 return 0;
}
-----------------------------------------------------------------------------