尝试CodeChef挑战“ATM” - 获取SIGSEGV运行时错误

时间:2013-07-31 16:18:55

标签: c runtime sigsegv

我目前刚开始学习C(因为PHP和相关语言更多是我的领域),所以我想我会开始挑战。

我决定使用CodeChef并尝试其中一个简单的练习挑战,但显然我的代码在运行时会出现SIGSEGV错误。

请您检查我的代码,看看为什么我收到此错误,代码在我尝试过的多个框上运行正常(Mac OSX,Linux(CentOS和Ubuntu))。

以下是代码:

#include <stdio.h>
#include <stdlib.h>

#ifndef BANK_CHARGE
  #define BANK_CHARGE  0.5
#endif;

int main (int argc, char **argv){
  // if(argc != 3){
  //   printf("Usage: %s [int] [float]\n", argv[0]);
  //   exit(1);
  // }

  int withdraw = atoi(argv[1]);
  float balance = atof(argv[2]);

  if((withdraw % 5) != 0){
    printf("%.2f", balance);
    exit(1);
  }
  if(withdraw > 2000 || withdraw == 0){
    printf("%.2f", balance);
    exit(1);
  }

  float totalWithdraw = (withdraw + BANK_CHARGE);

  if(totalWithdraw >= balance){
    printf("%.2f", balance);
    exit(1);
  }

  printf("%.2f", balance - totalWithdraw);
  return 0;
}

挑战位于:http://www.codechef.com/problems/HS08TEST

但这是问题摘要:

  

此问题的所有提交均可用。

     

Pooja希望从ATM取款X $ US。取款机将   如果X是5的倍数,则只接受交易,Pooja's   账户余额有足够的现金来执行提款交易   (包括银行手续费)。每次成功撤回银行   收费0.50美元。

     

尝试交易后计算Pooja的帐户余额。   输入

     

正整数0 < X <= 2000 - Pooja希望的现金数额   退出。

     

非负数0 <= Y <= 2000,精度为两位数 -   Pooja的初始账户余额。输出

     

在尝试交易后输出帐户余额,以a给出   精度为两位数的数字。如果没有足够的钱   帐户完成交易,输出当前银行   平衡。示例 - 成功交易

     

输入:30 120.00

     

输出:   89.50

     

示例 - 不正确的提款金额(不是5的倍数)

     

输入:42 120.00

     

输出:   120.00

     

示例 - 资金不足

     

输入:300 120.00

     

输出:   120.00

1 个答案:

答案 0 :(得分:1)

SIGSEGV - 段错误。这意味着您的程序的一部分实际上是在尝试从读取到您的程序未经许可的内存地址。

使用没有命令参数运行程序这样简单的操作可能会导致此操作系统错误,因为无法保证argv[1]argv[2]是您可以读取的有效内存位置。更有可能argv[1]argv[2]包含的随机数几乎肯定不是有效位置atoiatof可以读取的。不确定为什么你注释检查有效数量的参数,因为这可以保护你的程序免于犯这个罪。

我认为你在基于Unix的操作系统(如Linux)上运行,首先要获得SIGSEGV。因此,我建议您在GNU调试器(gdb)中运行程序,该程序还会显示导致此错误的代码行。使用调试器是一种伟大的学习技术,可以让您在将问题带到更广泛的社区之前解决问题。 (提示,提示)。