

以下のプログラムをコンパイルして、実行したところSegmentation fault(コアダンプ)と表示されてしまいます。

どこか間違っているでしょうか？

[code]

    #include <stdio.h>
    
    #define N 10
    #define NUM_SCORE 50
    
    int main ( void ) 
    {
    
        int i,j,n;
        int score[ NUM_SCORE ] = {
            1,  4,  9,  9,  8, 10, 10,  9,  5, 10, 
            2,  9,  6,  4,  0,  7,  3,  5,  6,  6, 
            7,  4,  2,  9,  2,  5,  5,  3,  1,  9, 
            5,  7,  3,  2,  7,  9,  1,  7,  6,  6, 
            5,  8,  2,  5,  3, 10,  6,  2,  2,  5, 
        };
    
        int histogram[ N+1 ]; /* 点数 i の学生の人数を格納する配列 histogram[i] */
    
        for( i = 0; i <= N; i++ )
        {   
            histogram[ i ] = 0;
        }
        
        for( j = 0; j <= NUM_SCORE; j++ )
        {
            histogram[ score[ j ] ]++;
        }
    
        /* 結果の表示 */
        printf("点数の分布は以下の通りです．\n");
        for ( i = 0; i <= N; i++ ) 
        {
            printf(" %2d点: %d\n ", i, histogram[i] );
        }
        n = 0;
        for ( i = 7; i <= N; i++ )
        {
            n = n + histogram[ i ];
        }
        printf( "7点以上の人は%d人います", n );
        
        return 0;
    
    }
    
[/code]


CC BY-SA 4.0
2020-11-21T07:28:12.677
72118
2020-11-21T11:42:17.980
2020-11-21T08:29:54.860
3060
42820
question
c
Segmentation fault (コアダンプ ) の原因が分からない


複合条件ですね。  
まずこの行の継続条件`j <= NUM_SCORE`が`=`を含んでいるために配列`score`のサイズをオーバーしているからです。

[code]

    for( j = 0; j <= NUM_SCORE; j++ )
    
[/code]

こちらが`score`の宣言

[code]

    int score[ NUM_SCORE ] = {
    
[/code]

このように宣言している場合、有効なインデックス値は`0`～`(NUM_SCORE - 1)`の範囲になります。  
そして`score`の範囲外のデータを基に以下の行で更に配列`histogram`の範囲外(ここは最大値+1といった値では無くもっと大きな値)をアクセスしてしまったのでしょう。  
そのためSegmentation fault(コアダンプ)になったと考えられます。

[code]

    histogram[ score[ j ] ]++;
    
[/code]

`for`ループ継続条件の`=`を外して`NUM_SCORE`未満とすれば問題なく動作します。

[code]

    for( j = 0; j < NUM_SCORE; j++ )
    
[/code]

* * *

別の`N`を使ったループは、対象配列の`int histogram[ N+1 ];`が`N+1`個の領域で確保されているため、こちらは

[code]

    for ( i = 0; i <= N; i++ )
    
[/code]

とか

[code]

    for ( i = 7; i <= N; i++ )
    
[/code]

でループしても問題無い訳です。  
(ただし、配列のインデックス値の範囲としては問題無いですが、実際に行うべき処理として問題無いかどうかは別です。今回は大丈夫そうですが、#defineマクロの数値の意味付けは気を付けた方が良いでしょう。)

* * *

短いプログラムの中で、配列の要素数の宣言の仕方が混在していることも、誤解を生みやすい原因でしょう。


CC BY-SA 4.0
2020-11-21T07:37:30.813
72119
2020-11-21T08:39:55.597
2020-11-21T08:39:55.597
26370
26370
72118
answer


参考情報として、使用している C コンパイラが gcc の場合、配列の範囲外アクセス(`out of bounds
access`)に対して警告(warning)を表示するオプションが用意されています。

**gcc(1)**

> **-Warray-bounds**  
>  **-Warray-bounds=n**  
>  This option is only active when -ftree-vrp is active (default for -O2 and
> above). It warns about subscripts to arrays that are always out of bounds.
> This warning is enabled by -Wall.  
>  
>  **-Warray-bounds=1**  
>  This is the warning level of -Warray-bounds and is enabled by -Wall; higher
> levels are not, and must be explicitly requested.  
>  
>  **-Warray-bounds=2**  
>  This warning level also warns about out of bounds access for arrays at the
> end of a struct and for arrays accessed through pointers. This warning level
> may give a larger number of false positives and is deactivated by default.
[code]

    $ gcc --version
    gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
    
    $ gcc -O2 -Warray-bounds -o histogram histogram.c
    histogram.c: In function ‘main’:
    histogram.c:27:21: warning: iteration 50 invokes undefined behavior [-Waggressive-loop-optimizations]
       27 |     histogram[ score[ j ] ]++;
          |                ~~~~~^~~~~
    histogram.c:25:3: note: within this loop
       25 |   for( j = 0; j <= NUM_SCORE; j++ )
          |   ^~~
    
[/code]

その他に [cppcheck - A tool for static C/C++ code
analysis](https://sourceforge.net/p/cppcheck/wiki/Home/) を利用しても同様の結果が得られます。

[code]

    $ cppcheck --enable=all histogram.c 
    Checking histogram.c ...
    histogram.c:27:21: error: Array 'score[50]' accessed at index 50, which is out of bounds. [arrayIndexOutOfBounds]
        histogram[ score[ j ] ]++;
                        ^
    
[/code]


CC BY-SA 4.0
2020-11-21T11:29:14.333
72123
2020-11-21T11:42:17.980
2020-11-21T11:42:17.980
72118
answer