【解決方法】オンライン サーバーでは C++ SIGSEGV セグメンテーション エラーが発生するが、ローカル マシンでは発生しない場合の最善の方法についてのアドバイスはありますか?

プログラミングQA


5 つの数値セットの最大値と最小値の合計を計算するために、Hackerrank チャレンジを行っています。 例えば ​​:

Sample Input
1 2 3 4 5

Sample Output
10 14

出力 10 = 最小合計 (最大値を除外)、および 14 = 最大合計 (最小値を除外)。 各配列入力の制約は次のとおりです。 1 <= a[i] <= 10^9、それは具体的に使用するように指示します uint64_t 合計出力用。 タスクの元の Web サイトは次のとおりです。. 私のコードはローカル マシン (Ubuntu 22.04) で動作しますが、2 つの入力ケースの両方で送信中に SIGSEGV セグメンテーション エラーが発生しました。

1 2 3 4 5
7 69 2 221 8974

エラーは次のとおりです。

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000000004023fd in compute (array_members=...) at Solution.cpp:45
45	    unsigned long array_smallest = array_members[0];

私が試したこと:

これが私のコードです:

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;
vector<unsigned long> array_members;

void input(){
    int array_size = 0;
    const unsigned long max_value = 1000000001;
    
    do {
        cin >> array_size;
    }   while (array_size < 0|| array_size > 6);
    cin.ignore(256, '\n');
    
    string input;
    int data = 0;
    getline(cin, input);
    istringstream iss(input);
    while (iss >> data){
        if (data > 0 && data < max_value){
            array_members.push_back(data);
        } else cerr << "Data out of bounds" << endl;
    }

    /** PRINT ARRAY
    for (int i =0;  i < array_size; i++){
        cout << array_members[i];
    } **/
}

void compute (vector<unsigned long> &array_members){
    unsigned long array_smallest = array_members[0];
    unsigned long array_biggest  = array_members[0];
    uint64_t sum = 0;

    for (int i =0; i < array_members.size(); i++){
	    sum += array_members[i];
	
        if (array_members[i] > array_biggest)  
            array_biggest  = array_members[i];
        if (array_members[i] < array_smallest) 
            array_smallest = array_members[i];
    }
    cout << sum-array_biggest << " " << sum-array_smallest << endl;
}

int main(){
    input();
    compute(array_members);
    return 0;
}

このコードは私のマシンで動作します。 私が試したこと:
1. すべての変数が初期化されていることを確認しました。
2. 最大制約は 10^9 であるため、入力として 10^9 を使用して GDB で確認しました。

1000000000 1000000000 1000000000 1000000000 1000000000
4000000000 4000000000

正常に動作し、GDB はプログラムが正常に終了したことを報告しました。 サーバーの範囲が異なる可能性がありますか? 使用するために具体的に言及されたタスク uint64_t.

他に何を確認すればよいかわかりません。アドバイスはありますか?

[Additional]

完全なエラー レポート:
– サンプル テスト ケース 0

Compiler Message

Segmentation Fault
Error (stderr)
    Reading symbols from Solution...done.
    [New LWP 935423]
    Core was generated by './Solution'.
    Program terminated with signal SIGSEGV, Segmentation fault.
    #0  0x00000000004023fb in compute (array_members=...) at Solution.cpp:44
    44	    unsigned long array_smallest = array_members[0];

Input (stdin)
    1 2 3 4 5

Your Output (stdout)
~ no response on stdout ~

Expected Output
    10 14

– サンプル テスト ケース 1

Compiler Message

Segmentation Fault
Error (stderr)
    Reading symbols from Solution...done.
    [New LWP 2338644]
    Core was generated by './Solution'.
    Program terminated with signal SIGSEGV, Segmentation fault.
    #0  0x00000000004023fb in compute (array_members=...) at Solution.cpp:44
    44	    unsigned long array_smallest = array_members[0];

Input (stdin)
    7 69 2 221 8974

Your Output (stdout)
~ no response on stdout ~

Expected Output
299 9271

解決策 1

C++
while (array_size < 0 && array_size > 6);

の値 array_size 同時に 0 未満と 6 を超えることはできません。 したがって、どちらか一方でなければなりません。

C++
while (array_size < 0 || array_size > 6); // less than zero OR greater than six.

それ以外では、なぜそれが 45 行目で SEGV になるのかを理解するのは困難です。プログラムへの入力の値に依存する可能性があります。

解決策 2

45 行目に SEGV がある理由が見当たらないという点で、私は Richard と同意見です。しかし、問題文には、入力が 5 つの整数からなる 1 行であると書かれています。 あなたのプログラムは、ここに示されているように、最初の行は配列のサイズで、2 番目の行はデータです。 サンプルは出力を生成しませんが、これは特定のサンプルによって裏付けられているようです。 私は HackerRank に詳しくありませんが、私の経験では、これらのサイトは単にコードを実行し、成功、失敗、または時間制限違反を報告するだけです。 実行時エラーが報告されたことも、使用された入力データに関する手がかりも見たことがありません。そのため、プログラムが失敗しているテスト ケースが何であるかを知る方法がわかりません。 しかし、HackerRank が失敗時にそれを提供してくれるのではないでしょうか?
いずれにせよ、配列サイズを読み取るコードを削除することから始めて、再送信します。

コメント

タイトルとURLをコピーしました