0

電卓をプログラムしようとしていて、修正できないエラーに遭遇しました。実行する計算を入力すると、セグメンテーション違反が発生します。セグメンテーション違反はメモリが不足したときだと思ったので、両方のループが問題であると想定して削除しようとしましたが、うまくいきませんでした。

それは私のmallocでしょうか?

int calculator()
{
int exit = (int *)malloc(sizeof(int));
exit = 1;
while(exit == 1){

    printf("Welcome to the calculator, please enter the calculation you wish to make, if you wish to exit type EXIT\n");

    float *num1 = (float *)malloc(sizeof(float));
    float *num2 = (float *)malloc(sizeof(float));
    char operation = (char *)malloc(sizeof(char));
    float *ans = (float *)malloc(sizeof(float));
    char *string = (char *)malloc(10*sizeof(char));

    scanf("%s", &string);
    int result = strncmp(string, "EXIT", 10);

    if(result == 0){
        exit = 0;
    }
    else{
        //scanf("%f%c%f", &num1, &operation, &num2);
        int length = strlen(string);
        int i;
        for(i = 0; i <= length; i++){
            printf("forever");
            if(isdigit(string[i]) != 0){
                num1 = string[i];
            }
            else{
                operation = string[i];
            }
        }
        printf("num1%f\n", num1);
        printf("operation%c\n", operation);
        printf("num2%f\n", num2);

        if(operation == '+'){
            *ans = *num1 + *num2;
        }
        if(operation == '-'){
            *ans = *num1 - *num2;
        }
        if(operation == '/'){
            *ans = *num1 / *num2;
        }
        if(operation == '*'){
            *ans = *num1 * *num2;
        }
        if(operation == '^'){
            *ans = (float)pow(*num1,*num2);
        }

        printf("Your answer is %f\n", ans);

        }
}
return 0;
}

出力例:

電卓へようこそ。タイプ EXIT 5+9 を終了する場合は、実行する計算を入力してください。セグメンテーション違反 (コア ダンプ) プロセスが 139(0x8B) を返しました

malloc を使用した理由は、変数に割り当てた値が for ループを終了したときに失われたためです。これで問題は解決していませんが、コードに根本的な問題があると感じています。

4

3 に答える 3

5
char operation = (char *)malloc(sizeof(char));

する必要があります

char operation; // you don't need to call malloc for a single byte

と:

int exit = (int *)malloc(sizeof(int));

する必要があります

int exit;

実際、プログラム内のほとんどのデータは で割り当てられていますmallocが、そうである必要はありません。これらがコードに問題を引き起こしている理由は、ポインタを非ポインタ変数に割り当てているためです。

また:

scanf("%s", &string);

する必要があります

scanf("%s", string); // string is already declared as a pointer

ユーザーが入力したデータをポインターが指す割り当てられたスペースではなく、ポインターのアドレスに格納しているため、これによりセグメンテーション違反が簡単に発生する可能性があります。

ここでも同じです:

printf("Your answer is %f\n", ans);

次のようにする必要があります。

printf("Your answer is %f\n", *ans);

そしてここ:

printf("num1%f\n", num1);
// should be 
printf("num1%f\n", *num1);

そしてここ:

printf("num2%f\n", num2);
// should be 
printf("num2%f\n", *num2);

そして、ここで何が起こっているのですか?

num1 = string[i];

これはうまくいきません。文字をポインターにキャストすると、floatガベージが出力されます。

このコードの問題のほとんどは、ポインタの不適切な使用によるものです。少なくとも障害を修正するときは、すべてのポインターをコンパイル時のデータに変更することをお勧めします。また、プログラムの最後にデータを解放していません。これにより、メモリ リークが発生します。これは、 への呼び出しを廃止するもう 1 つの理由ですmalloc

当分の間、ポインターを一緒に使用しないようにしてください。

また:

セグメンテーション違反は、メモリが不足したときだと思いました

あまり。メモリ内の無効な場所を読み書きしようとすると、セグメンテーション違反が発生します。null ポインターが malloc を返したことが原因である可能性があります (メモリ不足が原因である可能性があります) が、さらに多くの理由が考えられます。

編集:

プログラムの非ポインターの例を次に示します。

#include <stdio.h>

int main (){

    char input[50];

    char operation = 0;
    float   num1 = 0.0f,
            num2 = 0.0f,
            ans  = 0.0f;

    printf ("Enter the calculation\n");

    scanf ("%f %c %f", &num1, &operation, &num2);

    if (operation == '+') printf ("The answer is %f\n", num1 + num2);

    return 0;
}
于 2013-06-20T21:45:46.140 に答える