メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

フレキシブル配列メンバーをもつ構造体の不適切な使用

メモリの割り当てによるフレキシブル配列メンバーの無視

説明

この欠陥は、以下の場合に発生します。

  • コンパイル時に、サイズ不明のフレキシブル配列メンバーをもつオブジェクトを定義する。

  • フレキシブル配列メンバーをもつ構造体の間で、memcpy() または類似の関数を使用せずに代入を行う。

  • フレキシブル配列メンバーをもつ構造体を関数の引数として使用し、引数を値渡しする。

  • 関数がフレキシブル配列メンバーをもつ構造体を返す。

フレキシブル配列メンバーは配列サイズが指定されていない、少なくとも 2 つの名前付きメンバーをもつ構造体の最後の要素です。

リスク

フレキシブル配列メンバーのサイズが定義されていない場合、そのフレキシブル配列メンバーを含む構造体のメモリ割り当て時にフレキシブル配列メンバーは無視されます。そのような構造体へのアクセスには、未定義の動作があります。

修正方法

  • malloc() または類似の関数を使用して、フレキシブル配列メンバーをもつ構造体のメモリを割り当てます。

  • memcpy() または類似の関数を使用して、フレキシブル配列メンバーをもつ構造体をコピーします。

  • フレキシブル配列メンバーをもつ構造体を関数の引数としてポインターで渡します。

すべて展開する

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>


struct example_struct
{
    size_t num;
    int data[];
};

extern void arg_by_value(struct example_struct s);

void func(void)
{
    struct example_struct *flex_struct;
    size_t i;
    size_t array_size = 4;
    /* Dynamically allocate memory for the struct */
    flex_struct = (struct example_struct *)
        malloc(sizeof(struct example_struct) + sizeof(int) * array_size);
    if (flex_struct == NULL)
    {
        /* Handle error */    
    }
    /* Initialize structure */
    flex_struct->num = array_size;
    for (i = 0; i < array_size; ++i)
    {
        flex_struct->data[i] = 0;
    }
    /* Handle structure */
	
	/* Argument passed by value. 'data' not 
	copied to passed value. */
    arg_by_value(*flex_struct); 
	
    /* Free dynamically allocated memory */
    free(flex_struct);
}
        
      

この例では、flex_structarg_by_value に引数として値渡しされています。その結果、渡す引数にフレキシブル配列メンバー データがコピーされていません。

修正 — 関数に構造体をポインターで渡す

渡す引数に構造体のすべてのメンバーをコピーするには、flex_structarg_by_pointer にポインターで渡します。

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>


struct example_struct
{
    size_t num;
    int data[];
};

extern void arg_by_pointer(struct example_struct *s);

void func(void)
{
    struct example_struct *flex_struct;
    size_t i;
    size_t array_size = 4;
    /* Dynamically allocate memory for the struct */
    flex_struct = (struct example_struct *)
        malloc(sizeof(struct example_struct) + sizeof(int) * array_size);
    if (flex_struct == NULL)
    {
        /* Handler error */       
    }
    /* Initialize structure */
    flex_struct->num = array_size;
    for (i = 0; i < array_size; ++i)
    {
        flex_struct->data[i] = 0;
    }
    /* Handle structure */
	
	/* Structure passed by pointer */
    arg_by_pointer(flex_struct); 
	
    /* Free dynamically allocated memory */
    free(flex_struct);
} 

結果情報

グループ: プログラミング
言語: C | C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: FLEXIBLE_ARRAY_MEMBER_STRUCT_MISUSE
影響度: Low

バージョン履歴

R2017b で導入