2

私は最近CPrimerPlusを読んでいます。これは、第10章のプログラミングプラクティスNo.4のために書いたコードで、二重型配列の最大数のインデックスを見つけます。配列サイズを手動で指定するために、可変長配列を使用しました。

#include <stdio.h>
int findmax(const double array[], int s);
//find the index of the largest number in the array
int main(void)
{
    int size = 0; //size of the array
    int index = 0; //index of the largest number
    double num[size]; //the array holding double-type numbers

    printf("Enter the size of the array: ");
        scanf("%d", &size);
    printf("Enter %d numbers: ", size);
    for (int i = 0; i < size; i++)
        scanf("%lf", &num[i]);

    index = findmax(num, size);
    printf("The index of the max number in the array is: %d\n", index);
    return 0;
}

int findmax(const double array[], int s)
{
    int index = 0;
    double max = array[0];
    for (int i = 0; i < s; i++)
            if (array[i] > max)
            {
                max = array[i];
                index = i;
            }
    return index;
}

このプログラムは、MinGWを使用して正常にコンパイルされます(プログラムファイル名がprog.cであると想定します)。

gcc prog.c -o prog.exe -std=c99

「サイズ」バリアルベが5未満の場合、プログラムは正常に動作します。ただし、「サイズ」バリアルベに6以上の数値を入力すると、実行時にプログラムがクラッシュします。

大まかに翻訳すると、エラーメッセージは次のようになります。

the memory 0x00000038 used by 0x77c1c192 could not be "written".

可変長配列の使用を排除しようとしましたが、プログラムは正常に動作しているようです。しかし、私はまだ元のもののどこが間違っているのかを知ることができませんでした。

4

6 に答える 6

3

numを割り当てるときのサイズは0です。割り当てられていないnum[0]にアクセスしようとすると、後でアクセス違反が発生します。

編集:サイズが読み取られた後、ダイナミックメモリを使用するかnumを宣言することを提案します。

于 2012-05-31T10:41:01.357 に答える
1

The program works fine when the "size" varialbe is less than 5.これは最も危険な種類のプログラミングエラーです。正常に動作しているように見えますが、実際には動作しません。配列に書き込むことにより、配列には長さがまったくないため、他の目的で要求されているメモリにすぐに書き込むことになります。size事後に変数を変更するだけで配列のサイズを変更することはできません。

1つのオプションはsize、配列を宣言する前に決定することです。もう1つは、を使用して動的割り当てを実行するnewことですが、これについてはいくつかの章で説明します。

于 2012-05-31T10:44:10.060 に答える
1

double num[size]; サイズ変数のユーザーからサイズを入力した後、ステートメント を入力します。

于 2012-05-31T10:42:41.677 に答える
1
int size = 0; //size of the array
    int index = 0; //index of the largest number
    double num[size]; //the array holding double-type numbers

    printf("Enter the size of the array: ");
        scanf("%d", &size);

を最初に宣言するnum arrayと、サイズはゼロになります。これは、その行が実行されたときのsizeの値ですが、後で再びsizeの値を読み取る可能性があります。

于 2012-05-31T10:46:44.433 に答える
1

配列を作成するとき、他の人がすでに指摘しているように、配列のサイズはゼロになります。したがって、要素を配列に埋めようとすると、使用可能なメモリがなくなり、他のメモリに上書きされて、最終的にメモリが破損します。

この問題を回避するために、以下のようにコードを書き直すことができます。

int size = 0; //size of the array     
int index = 0; //index of the largest number     
double *num = NULL; //Change it to a pointer      
printf("Enter the size of the array: ");         
scanf("%d", &size);     
num = malloc(size * sizeof(double));
if(NULL == num)
{
  printf("Malloc Failed\n");
  return 0;
}
printf("Enter %d numbers: ", size);     
for (int i = 0; i < size; i++)         
scanf("%lf", &num[i]); 

また

int size = 0; //size of the array     
int index = 0; //index of the largest number     
printf("Enter the size of the array: ");         
scanf("%d", &size);     

double num[size]; //Now, num will have proper size
printf("Enter %d numbers: ", size);     
for (int i = 0; i < size; i++)         
scanf("%lf", &num[i]); 

これは、C99の可変長配列が引き起こす可能性のあるいくつかの潜在的な問題について説明しているC99の可変長配列に関する有益な記事へのリンクです。

于 2012-05-31T11:07:44.813 に答える
1

他の人が示唆しているように、malloc()を使用することがこれを行う正しい方法です。それ以外の場合は、配列を任意の大きなサイズにして、いっぱいになったら入力の受け入れを停止することができます。

于 2012-05-31T20:21:06.040 に答える