Like in my title, my goal is to use the producer consumer model to mimic the linux cat command(ouput the contents of the file to screen). When I try running the program using lab3 5 animals.txt (lab3 the compiled/renamed executable, 5 being the size of the bounded buffer, and test_alarm.cpp being the name of the file to be printed), lines in the ouput seem to have been outputted multiple times. I am not sure what could be causing this(maybe I am not deleting the contents of the buffer properly? Though I'm not sure why that would cause multiple prints), so any help is appreciated.
An oddpoint is when I change the positions of 'ifstream infile' from global to the producer func, the output seems to change as well.
Animals.txt (output using linux's 'cat')
I have a dog
Dogs are large
I also have a cat
Animals.txt (output using my program)
I have a dog
Dogs are large
I also have a cat
I have a dog
Dogs are large
I also have a cat
I have a dog
Dogs are large
I have a dog
(Latest output)
counter in prod is: 1
counter in prod is: 2
counter in prod is: 3
I have a dog
counter in consumer is: 3
Dogs are large
counter in consumer is: 2
Segmentation fault (core dumped)
code
#include <iostream>
#include <string>
#include <semaphore.h>
#include <fstream>
#include <unistd.h>
#include <mutex>
#include <condition_variable>
#include <thread>
using namespace std;
int counter = 0; //number of words in buffer
int buffmax; //size of buffer
string filename;
mutex mu;
condition_variable cond;
string* buffer;
bool flag = false;
ifstream infile; 
void produce()
{
        
        infile.open(filename);
        while(getline(infile, temp)) //!infile.eof()
        {
                unique_lock<mutex> locker(mu);
                cond.wait(locker, []() {return counter < buffmax; }); //if true then produce, if false then wait
                buffer[counter] = temp;
                //infile >> buffer[counter];
                counter++;
                //cout << "counter in prod is: " << counter << endl;
                locker.unlock();
                cond.notify_one(); //notify consumer thread
        }
        infile.close();
        flag = true;
}
void consume()
{
        
        while(true)
        {
                if (flag == true && counter <= 0)
                        break;
        unique_lock<mutex> locker(mu);
                cond.wait(locker, []() {return counter > 0; });
           
                cout << buffer[0] << endl;
                string *x = new string[buffmax];
                for(int i = 0; i < counter-1; i++) // reason for seg fault?
                {
                   x[i]=buffer[i+1];
                }
                delete [] buffer;
                buffer = NULL
                buffer = x;
                x = NULL;
                //cout << "counter in consumer is: " << counter << endl;
                counter--;
                
                locker.unlock();
                cond.notify_one(); //notify producer thread
        }
}
int main(int argc, char* argv[])
{
    string s = argv[1];
    buffmax = stoi(s); //size of the buffer
    filename = string(argv[2]); // name of file to be parsed
    buffer = new string[buffmax]; // creating the bounded buffer
    
    thread t1(produce);
    thread t2(consume);
    t1.join();
    t2.join();
    return 0;
}
 
    