簡體   English   中英

為什么下面的代碼會導致分段錯誤 (SIGSEGV)?

[英]Why does the code below causes Segmentation Fault (SIGSEGV)?

問題陳述 給定一個嚴格遞增的整數序列 A1,A2,…,AN。 你的任務是壓縮這個序列。

此序列的壓縮形式是由逗號(字符“,”)分隔的范圍序列。 范圍是一個整數或一對由三個點分隔的整數(字符串“...”)。 當壓縮形式的每個范圍 a...b 被解壓縮為子序列 (a,a+1,...,b) 時,我們應該再次獲得(逗號分隔的)序列 A。

對於 A 的每個最大連續子序列 (a,a+1,...,b) 使得 b≥a+2,A 的壓縮形式必須包含范圍 a...b; 如果 b≤a+1,這樣的序列不應該被壓縮到一個范圍內。 如果一個連續的子序列不能被 A 的至少一個元素擴展到它旁邊,那么它就是最大的。 可以證明,任何序列的壓縮形式都是唯一的(即明確定義的)。

輸入 輸入的第一行包含一個整數 T,表示測試用例的數量。 T 測試用例的描述如下。 每個測試用例的第一行包含一個整數 N。第二行包含 N 個空格分隔的整數 A1,A2,...,AN。 輸出 對於每個測試用例,打印一行包含一個字符串——給定序列的壓縮形式。

約束

1≤T≤100
1≤N≤100
1 ≤ Ai ≤ 1000 for each valid i
A1 < A2 < …... <AN

子任務

子任務 #1(100 分):原始約束

示例輸入

3
12
1 2 3 5 6 8 9 10 11 12 15 17
4
4 5 7 8
1
4

示例輸出

1...3,5,6,8...12,15,17
4,5,7,8
4

我的代碼:

#include <bits/stdc++.h>

using namespace std;
bool b[1005];
int a[1005];
int main()
{
    int test, i, j, size, count;
    cin >> test;
    while (test--)
    {

        for (i = 0; i < 1005; i++)
            b[i] = false;

        cin >> size;

        for (i = 0; i < size; i++)
        {
            cin >> a[i];
            b[a[i]] = true;
        }

        for (i = 0; i < 1005; i++)
        {
            if (b[i] == true)
            {
                cout << i;
                j = i;
                count = 0;
                while (b[j] == true)
                {
                    count++;
                    j++;
                }

                if (count > 2)
                {
                    i = j;
                    if ((j - 1) != a[size - 1])
                        cout << "..." << i - 1 << ",";
                    else
                        cout << "..." << i - 1;
                }
                if (count == 2)
                {
                    i = j;
                    if ((j - 1) != a[size - 1])
                        cout << "," << i - 1 << ",";
                    else
                        cout << "," << i - 1;
                }
                if (count == 1 && ((j - 1) != a[size - 1]))
                    cout << ",";
            }
        }
    }
    return 0;
}
}

我的問題:上面的代碼在我的設備上完美運行並提供所需的輸出。 但是當我將此解決方案提交給 Online Judge 時,它​​說分段錯誤。 可以肯定的是,從根本上說,我是在錯誤地訪問內存。 你能告訴我它在哪里嗎?

b 被定義為 bool[1005]

在這部分

for(i=0 ; i<4000 ; i++)
    b[i] = false;

您正在寫入錯誤值 4000 次,超出數組大小。 編譯器允許覆蓋數組,但在運行時會出現未定義的行為。 簡而言之:它可以或不能導致段錯誤。

鑒於輸入數據位於文件input.txt ,這是另一種方法:

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

class Reader {
public:
    Reader(const std::string& filename) :
        filename_(std::move(filename)), is_(filename_)
    {
        is_.exceptions( std::ifstream::failbit | std::ifstream::badbit );
    }

    int get_N() {
        int N;
        is_ >> N;
        return N;
    }

    std::vector<int> get_ints(int N) {
        std::vector<int> v;

        v.reserve(N);
        for (int i = 0; i < N; i++ ) {
            int value;
            is_ >> value;
            v.push_back(value);
        }
        return v;
    }

    int get_num_cases() {
        int num_cases;
        is_ >> num_cases;
        return num_cases;
    }

private:
    std::string filename_;
    std::ifstream is_;
};

bool start_range_cur( std::vector<int> &v, int j, int N )
{
    if ( j>= (N - 2) ) return false;
    return ((v[j+1] - v[j]) == 1) && ((v[j+2] - v[j+1]) == 1);
}

bool in_range_cur( std::vector<int> &v, int j )
{
    return (v[j+1] - v[j]) == 1;
}

void print_range( int min, int max, bool print_comma)
{
    std::cout << min << ".." << max;
    if (print_comma) std::cout << ",";
}

void print_single(int val, bool print_comma)
{
    std::cout << val;
    if (print_comma) {
        std::cout << ",";
    }
}

int main() {
    Reader is {"input.txt"};

    int num_cases = is.get_num_cases();
    for (int i = 0; i < num_cases; i++) {
        int N = is.get_N();
        std::vector<int> v = is.get_ints(N);
        bool in_range = false;
        int range_start;
        for( int j = 0; j< N; j++ ) {
            if (in_range) {
                if (j == (N - 1)) {
                    print_range(range_start, v[j], false);
                }
                else if (in_range_cur(v, j)) {
                    continue;
                }
                else {
                    print_range(range_start, v[j], true);
                    in_range = false;
                }
            }
            else {
                if (j == (N - 1)) {
                    print_single(v[j], false);
                }
                else if (start_range_cur(v, j, N)) {
                    in_range = true;
                    range_start = v[j];
                }
                else {
                    print_single(v[j], true);
                }
            }
        }
        std::cout << '\n';
    }

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM