Dhasneem
Dhasneem

Reputation: 4007

How to avoid "Segmentation Fault" in c program

I have written C program for Case Register. My program is working good. I used -Wall for compile. It didn't show any Warning.But the problem is, if I want to run it with bash loop such as .test.sh | ./caseRegister, the output is like the below:

:>>: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

That test.sh is:

#/bin/sh

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

Why my code is showing "segmentation Fault" for long run? Please anyone explain me the causes and prevention techniques to rectify it. Thank u in advance.

My Code is:

#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;
}

Upvotes: 2

Views: 21852

Answers (1)

Per Johansson
Per Johansson

Reputation: 6877

pd.array only has room for 1024 results. You have to check that no_prod is < 1024 before writing to it, otherwise you'll write in unallocated memory, which is what gives you a segmentation fault. Once no_prod reached 1024 you have to abort the program (I assume you haven't worked with dynamic allocation yet).

It's good practice to not actually write 1024 at the check though, but rather use a macro for the array size (don't worry about this if you haven't used macros either).

Upvotes: 1

Related Questions