C中的分段错误

时间:2013-06-20 21:40:38

标签: c segmentation-fault

我一直在尝试编程计算器并遇到了一个我无法解决的错误。一旦我输入要完成的计算,我就会出现分段错误。我认为分段错误就是内存耗尽,所以我尝试删除我的循环,假设它们是问题,但没有运气。

可能是我的mallocs吗?

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)执行时间:2.611s

我使用malloc的原因是因为当我退出for循环时,我分配给变量的值丢失了。虽然这还没有解决问题,但我觉得我的代码存在根本性的错误。

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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返回的地址,然后将其转换为整数。然后通过在下一行重新分配退出到1来永久丢失地址。由于地址现在永远丢失,因此您有一些分配给程序的内存,但无法再从程序代码中获取。这样的事情被称为内存泄漏,应该避免。

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

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

... code ...

/* just after exit isn't used anymore */
free(exit);

答案 2 :(得分: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);

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