【问题标题】:How to avoid "Segmentation Fault" in c program如何避免c程序中的“分段错误”
【发布时间】:2013-01-23 06:49:51
【问题描述】:

我为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;
}

【问题讨论】:

  • 您的代码有问题,很可能您使用的指针未指向您所期望的。使用调试器找出位置和原因。
  • 我认为我们需要查看 C 代码才能回答这个问题。
  • 分段错误意味着您的程序访问或执行了无效内存。你有一个错误。看到一些代码可能会帮助人们分析它,但首先你应该在上面运行一个调试器,看看你是否能自己弄清楚。
  • 使用 bash ulimit 设置限制以获得一些 core 转储。用gcc -Wall -g编译程序;使用gdbvalgrind 对其进行调试。分段违规表明程序 有错误。
  • @BasileStarynkevitch 如何使用 bash 循环运行 gdb?

标签: c linux segmentation-fault


【解决方案1】:

pd.array 只能容纳 1024 个结果。在写入之前,您必须检查 no_prod 是否

最好不要在检查时实际写入 1024,而是使用宏来确定数组大小(如果您也没有使用宏,请不要担心这一点)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    • 2012-10-12
    • 2018-11-18
    相关资源
    最近更新 更多