2016-04-09 26 views
-1

Web kameramı simüle eden küçük bir programım var. Böylece kareler (programımdaki verilerin değeri) 2 dosyaya ve ekrana kaydedilmelidir. Ama kodumu çalıştırdığımda bölümleme hatası alıyorum; benim hatam nerede Okuyucular - yazar: Segmentation fault C++

#include <iostream> 
#include <fstream> 
#include <pthread.h> 
#include <stdlib.h> 
#include <windows.h> 
#include <winbase.h> 

#ifdef WIN32 
# include <process.h> 
#else 
# include <time.h> 
#endif 

static void Error(const char *str) 
{ 
    std::cerr << str << std::endl; 
    exit(0); 
} 
class Data 
{ 
public: 
    Data() : refcount(0), value(0) {} 
    void ref() { refcount++; } 
    void unref() { refcount--; } 
    bool isUnused(){ return (refcount == 0); } 
    void setValue(int val){ value = val; } 
    void print(std::ostream &ostr) { ostr << value << std::endl; } 

private: 
    unsigned int refcount; 
    int value; 
}; 

class Buffer 
{ 
public: 
    Buffer() : lastProduced(0) {} 

public: 
    Data *getEmptyDataElement() 
    { 
     Data *d = 0; /* = empty data element */; 
     for (int i=0; i<BUFFERSIZE; i++) 
     { 
      if (storage[i].isUnused()) { 
       d = &storage[i]; 
       break; 
      } 
     } 

     return d; 
    } 

    Data *getLastProducedData(Data* previous) 
    { 
     // check if new element is available 
     Data *d = lastProduced; 
     d->ref(); 
     return d; 
    } 

    void publish(Data *d) /* update last produced, so getLastProducedData returns the correct element */ 
    { 
     lastProduced = d; 
    } 

    void release(Data *d) /* update handled element, to make it available via getEmptyDataElement */ 
    { 
     d->unref(); 
    } 

private: 
    static const int BUFFERSIZE = 10; 
    Data storage[BUFFERSIZE]; 
    Data *lastProduced; 
}; 

static void *start_thread(void *t); 
class Thread 
{ 
public: 
    Thread() : tid(0) {} 

    void start() 
    { 
     if(pthread_create(&tid, 0, start_thread, (void *) this) != 0) 
      Error("Error: failed to create thread"); 
    } 

    void wait() 
    { 
     void *status; 
     pthread_join(tid, &status); 
    } 

    static void sleep(unsigned int msecs) 
    { 
#ifdef WIN32 
     if(SleepEx(msecs, TRUE) != 0) 
      Error("Error: SleepEx interrupted"); 
#else 
     struct timespec timeout; // timeout value for wait function 

     // prepare timeout value 
     timeout.tv_sec = msecs/1000; 
     msecs -= timeout.tv_sec * 1000; 
     timeout.tv_nsec = (1000 * msecs) * 1000; 

     if(nanosleep(&timeout, 0) != 0) 
      Error("Error: nanosleep interrupted or failed"); 
#endif 
    } 

    virtual void run() = 0; 

private: 
    pthread_t tid; 
}; 

static void *start_thread(void *t) 
{ 
    reinterpret_cast<Thread *>(t)->run(); 
    return 0; 
} 

class Producer : public Thread 
{ 
public: 
    Producer(Buffer &b, long sequenceNumber) : buffer(b), sequenceNumber(sequenceNumber) {} 

private: 
    void run() 
    { 
     for(int i = 0; i < 1000; ++i) 
     { 
      Data *d = buffer.getEmptyDataElement(); 
      produceData(d); 
      buffer.publish(d); 
     } 
    } 

    void produceData(Data *d) 
    { 
     Thread::sleep((float(rand())/RAND_MAX) * 1000); // sleep between 0 and 1 sec 
     d->setValue(sequenceNumber++); 
     d->print(std::cout); 
    } 

    Buffer &buffer; 
    long sequenceNumber; 
}; 


class Handler : public Thread 
{ 
public: 
    Handler(Buffer &b, std::ostream &ostr) : buffer(b), ostr(ostr) {} 

private: 
    void run() 
    { 
     Data *previous = 0; 
     while(1) 
     { 
      Data *d = buffer.getLastProducedData(previous); 
      handleData(d); 
      buffer.release(d); 
      previous = d; 
     } 
    } 
    void handleData(Data *d) 
    { 
     d->print(ostr); 
     Thread::sleep((float(rand())/RAND_MAX) * 1000); // sleep between 0 and 1 sec 
    } 

    Buffer &buffer; 
    std::ostream &ostr; 
}; 

int main() 
{ 
    Buffer buff; 

    std::ofstream file1; 
    std::ofstream file2; 

    file1.open ("file1.txt"); 
    file2.open ("file2.txt"); 
    // open the files 

    Producer p(buff, 0); 
    Handler h1(buff, std::cout), h2(buff, file1), h3(buff, file2); 

    p.start(); 
    h1.start(); 
    h2.start(); 
    h3.start(); 

    p.wait(); 
    h1.wait(); 
    h2.wait(); 
    h3.wait(); 
    // wait until producers stopped producing and handlers handled all produced data 

    return EXIT_SUCCESS; 
} 

kimse bir yere bence bir kilitlenme var, biliyor mu ama nerede bilemiyorum. Eğer için ya da başka bir hatam ama eğer aradığınız hatam eğer bu şekilde Buffer::getEmptyDataElement() yazarken

+0

bir [MCVE] oluştur için – user2079303

cevap

0

Ben dönebilmek

Data *getEmptyDataElement() 
{ 
    Data *d = 0; /* = empty data element */; 
    for (int i=0; i<BUFFERSIZE; i++) 
    { 
     if (storage[i].isUnused()) { 
      d = &storage[i]; 
      break; 
     } 
    } 

    return d; 
} 

Eğer bir fonksiyon yazmak ... bilmiyorum NULLData işaretçisi (tüm depolar kullanıldığında).

bunu test etmeden Producer::run()

void run() 
{ 
    for(int i = 0; i < 1000; ++i) 
    { 
     Data *d = buffer.getEmptyDataElement(); 
     produceData(d); 
     buffer.publish(d); 
    } 
} 

Eğer Producer::produceData() için d işaretçi geçmesi halinde, kullanmak ama önce dönen işaretçi test etmek ve

void produceData(Data *d) 
{ 
    Thread::sleep((float(rand())/RAND_MAX) * 1000); // sleep between 0 and 1 sec 
    d->setValue(sequenceNumber++); // what if 'd' is NULL? 
    d->print(std::cout);   // what if 'd' is NULL? 
} 

Producer::produceData() kullanmak, bu iyi olabilir NULL ise test edilmeden.

Potansiyel çökme. lastProduced kullanan Buffer::getLastProducedData() ile

aynı potansiyel sorun

Data *getLastProducedData(Data* previous) 
{ 
    // check if new element is available 
    Data *d = lastProduced; 
    d->ref(); // what if 'lastProduced' (and so 'd') is NULL? 
    return d; 
} 

Neyse onu test etmeden (?? O Producer::run()Producer::produceData() eğer testin değeri elde test edilmemiş değeri üzerinden publish() tarafından alınan NULL olabilir): Bize vermelidir file1.txt ve file2.txt programınızı izleyebilmemiz için.

P.S. .: üzgün benim kötü İngiliz