为什么我的程序在运行后会出现“分段错误”(核心转储)错误

时间:2014-11-25 11:36:22

标签: c++ qt g++ semaphore

我使用信号量创建一个质数检查器。代码执行直到"找到来自"部分和之后崩溃说"分段故障(核心转储)"。在搜索了这个之后,我明白当程序试图访问一部分不可用的内存时会发生这种情况。但是我的代码中没有理解它。请看看,谢谢!

#include <QThread>
#include <QSemaphore>
#include <QMutex>
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <vector>

using namespace std;

#define TOTALSPACE 50

vector<int> buffer(TOTALSPACE);
QSemaphore space(TOTALSPACE), avail;
QMutex l;

int prime_from, prime_to, num_threads;
int total = 0, cnumber = 0;
int in = 0, out = 0;
bool b = false;

//-----Generator------
class Generator : public QThread
{
private:
    int strt;
    int end;

public:
    Generator(int a, int b)
    {
        strt = a;
        end = b;

        cnumber = strt;
    }

    void run()
    {
        while (cnumber < end)
        {
            space.acquire();
            cnumber++;
            buffer[in] = cnumber;
            in = (in + 1) % TOTALSPACE;
            avail.release();
        }

        b = true;

        for (int i = 0; i < num_threads; i++)
        {
            space.acquire();
            buffer[in] = -1;
            in = (in + 1) % TOTALSPACE;
            avail.release();
        }
    }
};

//-----------Checker----------
class Checker : public QThread
{
private:
    int number;

public:
    Checker() {}
    void run();
};

void Checker::run()
{
    while (1)
    {
        avail.acquire();
        l.lock();
        number = buffer[out];

        if (number == -1)
        {
            l.unlock();
            break;
        }

        bool isPrime = false;

        for (int i = 2; i <= sqrt(number); i++)
        {
            if (number%i == 0)
            {
                isPrime = true;
                break;
            }
        }

        out = (out + 1) % TOTALSPACE;

        if (isPrime == false)
        {
            total++;
        }

        l.unlock();
        space.release();
    }
}

//-------------Main---------
int main(int argc, char *argv[])
{
    num_threads = atoi(argv[1]);
    prime_from = atoi(argv[2]);
    prime_to = atoi(argv[3]);
    cout << " Number of Threads = " << num_threads << endl;
    cout << " Primes checking from " << prime_from << " to " << prime_to << endl;

    Generator gen(prime_from, prime_to);
    gen.start();
    Checker* thr[num_threads];

    for (int i = 1; i < num_threads; i++)
    {
        thr[i] = new Checker();
        thr[i]->start();
    }

    gen.wait();

    for (int i = 0; i < num_threads; i++)
    {
        thr[i]->wait();
    }

    cout << "Total Primes: " << total << endl;
    return 0;
}

1 个答案:

答案 0 :(得分:3)

有几件事可能导致这种情况发生。首先,你永远不会检查是否提供了足够的参数(argc>3)。因此,您可以将无效指针传递给atoi

但更有可能的是,您没有初始化thr[0],因为您使用for (int i = 1;启动了初始化循环,但是您在循环中访问thr[0]以进行同步,因为您使用{{ 1}}。

另外值得注意的是,当您执行or (int i = 0;时,您使用的是可变长度数组,因为Checker* thr[num_threads];不是编译时常量。该功能目前不是C ++标准的一部分(不是在C ++ 14中)。所以,如果你想让你的程序可移植,你可以在最后做num_threadsChecker** thr = new Checker*[num_threads];,如果你想要勤奋(而不是使用智能指针)。