如何避免c程序中的“分段错误”

时间:2013-01-23 06:49:51

标签: c linux segmentation-fault

我为Case Register编写了C程序。我的计划运作良好。我使用-Wall进行编译。它没有显示任何警告。但problem is,如果我想使用bash loop .test.sh | ./caseRegister运行它,则输出如下所示:

:>>:1498.00
:>>:1499.00
:>>:1500.00
:>>:1501.00
:>>:1502.00
:>>:1503.00
:>>:1504.00
:>>:1505.00
:>>:1506.00
:>>:1507.00
:>>:1508.00
:>>:1509.00
:>>:1510.00
:>>:1511.00
:>>:1512.00
:>>:1513.00
:>>:1514.00
:>>:1515.00
:>>:1516.00
:>>:1517.00
:>>:1518.00
Segmentation fault

那个test.sh是:

#/bin/sh

i=1
run=1
for ((; ; ))
do
echo $i
#echo $((i++))
done

为什么我的代码显示"分段错误"长期来看?请任何人向我解释纠正它的原因和预防技巧。提前谢谢你。

我的代码是:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct prod_details
{
    int no_prod;
    double total;
    double array[1024];
}pd;

char *getinput(char *inp)
{
    printf(":");
    gets(inp);
    if(strlen(inp) > 11)
    {
        printf("Input is restricted to 10 character\n");
        getinput(inp);
    }
    return inp;
}

void print()
{
    printf("Grant Total is : %.2f\n",pd.total);
}

int check(char *str)
{
    int i,minusflag=0,plusflag=0,optrflag=0;
    if(strlen(str) == 0)
        return 0;
    if(str[strlen(str) -1] == '+' || str[strlen(str) -1] == '-' || str[strlen(str) -1] == '*')
    {
        printf("last operator\n");
        return 1;
    }

    if(str[0] == '-')
    {
        i=1;
        while(str[i] != '-' )
        {
            if(str[i] == '\0')
            {
                minusflag=1;
                break;
            }
            i++;
        }
        if(str[i] == '-')
        {
            minusflag=0;
            return 1;
        }
    }
    if(str[0] == '-')

    {
        i=1;
        while(str[i] != '+' )

        {
            if(str[i] == '\0')
            {
                minusflag=1;
                break;
            }
            i++;
        }
        if(str[i] == '+')
        {
            minusflag=0;
            return 1;
        }
    }
    if(str[0] == '-' && minusflag == 1)
        return 2;
    if(str[0] == '+')
    {
        i=1;
        while(str[i] != '+')
        {
            if(str[i] == '\0')
            {
                plusflag=1;
                break;
            }
            i++;
        }
        if(str[i] == '+')
        {
            plusflag=0;
            return 1;
        }
    }
    if(str[0] == '+')
    {
        i=1;
        while(str[i] != '-' )
        {
            if(str[i] == '\0')
            {
                plusflag=1;
                break;
            }
            i++;
        }
        if(str[i] == '-')
        {
            plusflag=0;
            return 1;
        }
    }
    if(str[0] == '+' && plusflag == 1)
        return 2;
    if(str[0] == '*')
        return 1;
    if((str[0] == '+' || str[0] == '-') && (str[1] == '+' || str[1] == '-' || str[1] == '*' || str[1] == '/'  ))
        return 1;

    for(i=0;i<strlen(str);i++)
    {
        if(((str[i] >= '!' && str[i] <= '/') || (str[i] >= ':' && str[i] <= '~')))
        {
            if(str[i] == '*' || str[i] == '+' || str[i] == '-' || str[i] == '/')
            {
                optrflag++;
            }
            else
                return 1;
        }
    }
    if(optrflag == 1)
        return 3;
    else if(optrflag > 1)
        return 1;
    return 2;
}

int expcalc(char *str)
{
    char copy[10];
    char op;
    char *temp;
    char numb[10],numf[10];
    printf("Start of expcal\n");
    int i;
    double result=0;

    for(i=0;i<strlen(str);i++)
    {
        if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
        {
            op = str[i];
        }
    }
    strcpy(copy,str);
    i=0;
    while(str[i] != op)
    {
        numf[i] = str[i];
        i++;
    }
    numf[i] ='\0';
    temp=strchr(copy,op);
    i=1;
    printf("\n");
    while(temp[i] != '\0')
    {
        numb[i-1] = temp[i];
        i++;
    }
    numb[i-1] = '\0';
    switch(op)
    {
        case '+':
            result=atof(numf)+atof(numb);
            break;
        case '-':
            result=atof(numf)-atof(numb);
            break;
        case '*':
            result=atof(numf)*atof(numb);
            break;
        case '/':
            result=atof(numf)/atof(numb);
            break;
        default:
            break;
    }
    printf("%.2f\n",result);
    if((pd.total+result) < 0)
    {
        printf("Couldn't calculate\n");
        return 0;
    }
    pd.array[pd.no_prod]=result;
    pd.total=pd.total+result;
    printf(">>:%.2f\n",pd.total);
    pd.no_prod++;
    return 0;
}

int calc(char *str)
{
    if((pd.total+atof(str)) < 0)
    {
        printf("Coundn't Calculate\n");
        return 0;
    }
    pd.array[pd.no_prod]=atof(str);
    pd.total=pd.total+pd.array[pd.no_prod];
    printf(">>:%.2f\n",pd.total);
    pd.no_prod++;
    return 0;
}
int call()
{
    int chkflg;
    char input[1024];
    getinput(input);
    chkflg=check(input);
    if(chkflg == 3)
    {
        expcalc(input);
        call();
    }
    else if(chkflg == 2)
    {
        calc(input);
        call();
    }
    else if(chkflg == 1)
    {
        printf("You have entered Wrogly!!!\n Please enter correctly\n");
        call();
    }
    else
    {
        print();
        return 1;
    }
    return 0;
}

int main()
{
    printf("..CASE  RIGISTER..\n");
    call();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

pd.array只有1024个结果的空间。你必须检查no_prod是否&lt;在写入之前1024,否则你将写入未分配的内存,这就是给你一个分段错误。一旦no_prod达到1024,你就必须中止程序(我假设你还没有使用动态分配)。

最好不要在支票上实际写入1024,而是使用宏来表示数组大小(如果你还没有使用宏,也不要担心这个。)