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 Segmentation fault (core dumped) Process returned 139(0x8B) 执行时间:2.611s

我使用 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指针时,它将打印出垃圾。

这段代码的大部分问题是由于指针的无效使用造成的。我建议,至少在您修复错误时,您更改所有指向编译时数据的指针。您也没有在程序结束时释放数据。这会导致内存泄漏——另一个取消对malloc.

也许暂时尽量避免一起使用指针。

还:

我认为分段错误是内存不足

并不真地。当您尝试读取/写入内存中的无效位置时,会发生分段错误。这可能是由于我的 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 回答
0

可能是这些台词

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

如果要分配 (int *) 则不要将其分配给 (int) 因为那不是同一类型。

你可能想要

int exit = 1;

或者如果你真的想使用指针

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

while (*exit == 0) {

通过分配

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

您有效地获取 malloc 返回的地址,然后将其转换为整数。然后,您通过在下一行将 exit 重新分配给 1 来永久丢失地址。由于地址现在永远丢失了,您有一些内存分配给您的程序,但不再可以从程序的代码中访问。这种事情称为内存泄漏,应该避免。

这意味着每次执行 malloc 时,将它与 free 配对通常是一个非常好的主意,如下所示:

/* near the beginning */
int* exit = (int *)malloc(sizeof(int));

... code ...

/* just after exit isn't used anymore */
free(exit);
于 2013-06-20T21:47:02.343 回答
0

多个问题:

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

你如何以整数存储指针?

更改

int exit = 1;

不会再来了。。!!

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

更改

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

String 是一个指针,不要发送指向 scanf() 的指针。

scanf("%s", &string);

更改

scanf("%s", string);

天哪,我认为您不想打印 ans 的地址:

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

更改

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

我不会谈论你的代码的奇怪逻辑。首先解决致命问题。

于 2013-06-20T21:54:49.347 回答