質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • C++

    4426questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

C++で以下のソースがランタイムエラーになる原因を教えてください

受付中

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,263
退会済みユーザー

退会済みユーザー

c++初心者です。

以下の問題を解いており、自分のパソコン(visual studio 2013)では正常に動作するのですが、
オンラインジャッジに提出するとランタイムエラーというものが出ます。


http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1511631#1

原因がわかる方がいましたら教えていただきたく存じます。
-------------------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include<string>
#include<sstream>
#define CAPACITY 9


namespace stoi{//stoiのエラーを回避するため名前空間で宣言した

    int stoi(std::string str){
        int ret;
        std:: stringstream ss;
        ss << str;
        ss >> ret;
        return ret;
    }

}
class OverDigit{

public:

    int num_a[CAPACITY];
    int num_b[CAPACITY];
    OverDigit(std::string str_a, std::string str_b);
    void ChangeDigit(std::string str,int num[]);
    void Add();
};

OverDigit::OverDigit(std::string str_a,std::string str_b){

    ChangeDigit(str_a, num_a); 
    ChangeDigit(str_b, num_b);

}

void OverDigit::ChangeDigit(std::string str, int num[]){

    std::vector <int> num_str(CAPACITY, 0);
    int loc = CAPACITY, k = 8;
    int str_Max, str_rest;

    str_Max = str.length() / CAPACITY;//
    str_rest = str.length() % CAPACITY;

        for (int j = str.length() - CAPACITY; str_Max > 0; j = j-CAPACITY){
        num_str[k] = stoi::stoi(str.substr(j, CAPACITY));
        loc = k;
        k--;
        str_Max--;
    }
    //最後に余り分の文字を配列に入れる
    
        if(str_rest!=0)num_str[loc - 1] = stoi::stoi(str.substr(0, str_rest));

    for (int j = 0; j < CAPACITY; j++){
    num[j]=num_str[j];
    }
}
//80桁までの足し算
void OverDigit::Add(){

    int num_ans[CAPACITY] = {};
    int fat,overflow=0,count=0;

    for (int j = CAPACITY-1; j >0; j--){
        if (num_a[j] + num_b[j]<=999999999){
            num_ans[j] = num_a[j] + num_b[j];
        }
        else if (num_a[j] + num_b[j] > 999999999){
            fat = (num_a[j] + num_b[j]) - 1000000000;
            num_ans[j] = fat;
            num_a[j - 1]++;        
        }

    }

     if (num_a[0] + num_b[0] > 99999999){
        overflow = 1;
     }
     else{
         num_ans[0]= num_a[0] + num_b[0];
         

     }

    if (overflow == 1){
        std::cout << "overflow" << std::endl;
    }
    else {
        for (int j = 0; j < CAPACITY; j++){
            if (num_ans[j] != 0){
                count++;
                std::cout << num_ans[j];

            }
            else if (num_ans[j] == 0 && count >= 1){
                std::cout << "000000000";
            }

        }std::cout << std::endl;
    }

};


int main(){
    

    //vector配列を用いた80桁の計算
    int N;
    std::string str_a, str_b;

    std::cin >> N;
    std::cin.ignore();

    for (int i = 0; i < N; i++){
        getline(std::cin, str_a);
        getline(std::cin, str_b);
        OverDigit OverDigit_a(str_a,str_b);//オブジェクト
        OverDigit_a.Add();
    }

    return 0;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

0

num_a[j - 1]++; 

というところ、j==CAPACITY-1のときに範囲外メモリアクセスになりますね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/09/14 13:28

    j==CAPACITY-1のときは num_a[CAPACITY-2] だから範囲内では?

    キャンセル

  • 2015/09/14 13:46

    おおっと、そうです。ここは間違いじゃないです。

    キャンセル

0

与えられた数のオーバーフローチェックが抜けています。
Visual Studioでも82桁以上の数を入力すると落ちるのではないでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ChangeDigit()内の以下のループで、jに対するチェックがないので、jがマイナスになる可能性があります。

        for (int j = str.length() - CAPACITY; str_Max > 0; j = j-CAPACITY){ 
        num_str[k] = stoi::stoi(str.substr(j, CAPACITY)); 
        loc = k; 
        k--; 
        str_Max--; 
    } 

str_Maxでチェックするはずだったようにも思えますが、別に使わなくてもこんな感じでいいんじゃないでしょうか。

     for (int j = str.length() - CAPACITY; j >= 0 ; j = j - CAPACITY) { 
        num_str[k] = stoi::stoi(str.substr(j, CAPACITY)); 
        loc = k; 
        k--; 
    } 

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • C++

    4426questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。