I am writing a list-based multi-stack program. At first everything worked fine. Then I added a few exceptions. After that, the program began to build normally, but after throwing an exception, the program breaks. I opened the debugger and reached the place of error. There I found a place where another exception is thrown. But all that was written there is "MultiListStack.exe has triggered a breakpoint.". Please tell me, because of what it can be and how to fix it? Below I attach the code:
tmultiroot.h
//tmultiroot.h
//base abstract class for inheritance
#ifndef __MULTROOT_H__
#define __MULTROOT_H__
const int MemLimit = 4; // memory size
const int StackNum = 2; // number of stacks
typedef int TElem; // type of element
class TMultiRoot:
{
protected:
TElem Mem[MemLimit]; // memory for stacks (int array of MemLimit elements)
int DefaultStack; // current stack number
public:
TMultiRoot() { DefaultStack = 0; }
virtual bool IsEmpty(int ns) const = 0; // void control
virtual bool IsFull (int ns) const = 0; // overflow control
virtual void Put (int ns, const TData &Val) = 0; // put on the stack
virtual TData Get (int ns) = 0; // take from stack with deletion
// methods for working with the current stack
void SetDefaultStack(int ns) { DefaultStack = ns; } //current stack
int IsEmpty(void) const { return IsEmpty(DefaultStack); } // empty?
int IsFull(void) const { return IsFull (DefaultStack); } // full of?
void Put(const TData &Val) { Put(DefaultStack, Val); } // in the stack
TData Get(void) { return Get(DefaultStack); } // from the stack
};
#endif
multiliststack.h
//multiliststack.h
#ifndef __MULTILISTSTACK_H__
#define __MULTILISTSTACK_H__
#include "tmultiroot.h"
typedef int TElem; // type of element
class TMultiListStack: public TMultiRoot
{
protected:
int NextLink[MemLimit]; // next link index
int StackInd[StackNum]; // stack top index
int FirstFreeLink; // first free link index
public:
TMultiListStack();
virtual bool IsEmpty(int ns) const; // void control
virtual bool IsFull (int ns) const; // overflow control
virtual void Put (int ns, const TData &Val); // put on the stack
virtual TData Get (int ns); // take from stack with deletion
// utility methods
void Print(); // print stack values
int IsValid() { return 0; } // structure testing
};
#endif
exceptions.h
//exceptions.h
#ifndef _exceptions_h
#define _exceptions_h
//Exception class
class Exception{
protected:
int Line;
char* File;
char* Func;
char* Desc;
public:
Exception() {};//default constructor
Exception(int _Line, char* _File, char* _Func, char* _Desc); //constructor
Exception(const Exception& e); //copy constructor
~Exception(); //destructor
virtual void debug_print(); //display error message
virtual char* GetDesc(); //return error message
};
//stack exception class
class StackExc: public Exception {
protected:
int exc;//exception code, 0 - nomem, 1 - empty, 2 - full
public:
StackExc() {};//default constructor
StackExc(int _Line, char* _File, char* _Func, char* _Desc, int exc); //constructor
StackExc::~StackExc(); //destructor
int GetExc(); //get exception code
virtual void debug_print(); //display error message
};
#endif
ecxeptions.cpp
//exceptions.cpp
#include <cstring>
#include <iostream>
#include "exceptions.h"
//Exception class
Exception::Exception(int _Line, char* _File, char* _Func, char* _Desc) {
Line = _Line;
int size = strlen(_File) + 1;
File = new char[size];
strcpy(File, _File);
Func = new char[size];
strcpy(Func, _Func);
Desc = new char[size];
strcpy(Desc, _Desc);
}
//copy constructor
Exception::Exception(const Exception& e) {
Line = e.Line;
int size = strlen(e.File) + 1;
File = new char[size];
strcpy(File, e.File);
Func = new char[size];
strcpy(Func, e.Func);
Desc = new char[size];
strcpy(Desc, e.Desc);
}
//destructor
Exception::~Exception() {
delete[] File;
delete[] Func;
delete[] Desc;
}
//display exception
void Exception::debug_print() {
std::cerr << Line << " " << File << " " << Func << " " << Desc << std::endl;
}
char * Exception::GetDesc()
{
return Desc;
}
//stack exception class
StackExc::StackExc(int _Line, char* _File, char* _Func, char* _Desc, int exc)
: Exception(_Line, _File, _Func, _Desc), exc(exc) {
}
//destructor
StackExc::~StackExc() {
delete[] File;
delete[] Func;
delete[] Desc;
}
int StackExc::GetExc() {
return exc;
}
//display exception
void StackExc::debug_print() {
std::cerr << Desc << std::endl;
}
multiliststack.cpp
//multiliststack.cpp
#include <stdio.h>
#include "tmultiliststack.h"
#include "exceptions.cpp"
TMultiListStack::TMultiListStack()
{
for (int i = 0; i < MemLimit; i++)
NextLink[i] = i + 1;
NextLink[MemLimit - 1] = -1;
FirstFreeLink = 0;
for (int i = 0; i < StackNum; i++)
StackInd[i] = -1;
}
bool TMultiListStack::IsEmpty(int ns) const // void control
{
return StackInd[ns] < 0;
}
bool TMultiListStack::IsFull(int ns) const // overflow control
{
return FirstFreeLink < 0;
}
void TMultiListStack::Put(int ns, const TData &Val) // put on the stack
{
if (IsFull(ns)) {
throw StackExc(__LINE__, __FILE__, __FUNCTION__, "DataFull", 2); //after throwing this exception
} //it is being processed in main
else // And then an exception "MultiListStack.exe has triggered a breakpoint." occurs on this line
{
int k = FirstFreeLink;
FirstFreeLink = NextLink[k];
Mem[k] = Val;
NextLink[k] = StackInd[ns];
StackInd[ns] = k;
}
}
TData TMultiListStack::Get(int ns) // take from stack with deletion
{
TData temp = -1;
if (IsEmpty(ns))
throw StackExc(__LINE__, __FILE__, __FUNCTION__, "DataEmpty", 1);
else
{
int k = StackInd[ns];
temp = Mem[k];
StackInd[ns] = NextLink[k];
NextLink[k] = FirstFreeLink;
FirstFreeLink = k;
}
return temp;
}
void TMultiListStack::Print() // print stack values
{
int pind, ind, k;
for (int ns = 0; ns < StackNum; ns++)
{
printf("ns=%d -> ", ns);
pind = -1;
ind = StackInd[ns];
while (ind > -1) // pointer wrapping
{
k = NextLink[ind];
NextLink[ind] = pind;
pind = ind;
ind = k;
}
ind = pind;
pind = -1;
while (ind > -1) // pointer recovery and printing
{
printf("%d ", Mem[ind]);
k = NextLink[ind];
NextLink[ind] = pind;
pind = ind;
ind = k;
}
printf("\n");
}
}
main.cpp
#include <windows.h>
#include <conio.h>
#include <iostream>
#include "tmultiliststack.h"
using namespace std;
void main()
{
TMultiListStack mst;
int ms = 2, ns, code, temp, val = 0;
setlocale(LC_ALL, "Russian");
srand(1);
cout << "System Testing N Stacks" << endl;
while (1)
{
try {
val++;
code = random(4); // operation
ns = random(ms); // stack number
Sleep(1000);
if (code < 3) {
cout << "Put " << val << " in " << ns << endl;
mst.Put(ns, val);
mst.Print();
}
else {
cout << "Get from " << ns << endl;
temp = mst.Get(ns);
mst.Print();
}
}
catch (StackExc exc) {
exc.debug_print();
}
if (_kbhit())
break;
}
cout << "Stack Printing" << endl;
mst.Print();
}
When the program starts, 4 values are put on the zero stack. But at the fifth iteration, when the fifth value is to be added to the zero stack, overflow occurs. Because of this, my exception is thrown. Then it is processed in main. And after that, this incomprehensible exception is thrown. No details about it are displayed, so I don’t understand what to do. Tell me, please, how to fix it?
Related
This is a Stack class based on a dynamic array of struct for Depth First Search (DFS). The program is not able to run whenever it encounters the function, push(), which shows that the array is not successfully initialized in the constructor.
I have tried to look for the error and even changing the dynamic array of struct into parallel arrays but it still does not work. I apologize if the problem seems to be too simple to be solved as I do not have a strong foundation in C++.
#include <iostream>
#include <iomanip>
#ifndef HEADER_H
#define HEADER_H
using namespace std;
struct Value
{
int row; // row number of position
int col; // column number of position
//operator int() const { return row; }
};
class ArrayStack
{
public:
int top;
Value* array;
ArrayStack();
bool isEmpty();
bool isFull();
void push(int r, int c);
void pop();
int poprowvalue(int value);
int popcolvalue(int value);
int peekrow(int pos);
int peekcol(int pos);
int count();
void change(int pos, int value1, int value2);
void display();
void resize();
private:
int size;
};
ArrayStack::ArrayStack()
{
//Initialize all variablies
top = -1;
size = 10;
Value * array = new Value[size];
for (int i = 0; i < size; i++)
{
array[i].row = 0;
array[i].col = 0;
}
}
bool ArrayStack::isEmpty()
{
if (top == -1)
return true;
else
return false;
}
bool ArrayStack::isFull()
{
if (top == size - 1)
return true;
else
return false;
}
void ArrayStack::resize()
{
if (isFull())
size *= 2;
else if (top == size / 4)
size /= 2;
}
void ArrayStack::push(int r, int c)
{
if (isEmpty() == false)
resize();
array[top + 1].row = r;
array[top + 1].col = c;
top++;
}
void ArrayStack::pop()
{
int value;
if (isEmpty())
{
cout << "Stack underflow" << endl;
}
else
{
poprowvalue(array[top].row);
popcolvalue(array[top].col);
array[top].row = 0;
array[top].col = 0;
top--;
}
}
int ArrayStack::poprowvalue(int v)
{
return v;
}
int ArrayStack::popcolvalue(int v)
{
return v;
}
int ArrayStack::peekrow(int pos)
{
if (isEmpty())
cout << "Stack underflow" << endl;
else
return array[pos].row;
}
int ArrayStack::peekcol(int pos)
{
if (isEmpty())
cout << "Stack underflow" << endl;
else
return array[pos].col;
}
int ArrayStack::count()
{
return (top + 1);
}
void ArrayStack::change(int pos, int value1, int value2)
{
if (isEmpty())
cout << "Stack underflow" << endl;
else
{
array[pos].row = value1;
array[pos].col = value2;
}
}
void ArrayStack::display()
{
for (int i = size - 1; i > -1; i--)
{
cout << array[i].row << " " << array[i].col << endl;
}
}
#endif
I expect it to run well but an exception is always thrown on line 80, which is as follows:
Exception thrown at 0x00007FF6A160487C in Assignment1.exe: 0xC0000005: Access violation writing location 0x0000000000000000.
The problem is this line right here:
Value * array = new Value[size];
This declares a new array variable. You are allocating that array instead, and not your member variable array.
The answer is simple, just change it to this instead:
array = new Value[size];
Why can not I perform the following line?
delete [] target;
in my case?
Here is the code:
main.cpp
#include <iostream>
using namespace std;
#include "Char.h"
int main()
{
char * text = "qwerty";
char * a = new char[charlen(text)+1];
copyon(a,text);
cout<<a<<endl;
char * test = "asdfghjkl";
assign(&a, test);
assign(&a, a);
char * test1 = new char[26];
for (int i(0); i < 26; i++)
{
test1[i] = char(i+65);
}
test1[26] = '\0';
anotherAssign(test1, a);
cout << test1 << endl;
return 0;
}
Char.cpp
#include "Char.h"
#include <iostream>
#include <cassert>
#include <cstring>
size_t charlen(const char * ps)
{
size_t len=0;
while (ps[len++]);
assert(len-1==strlen(ps));
return len;
}
void assign(char** target, const char* source)
{
if (*target==source)
return;
delete [] *target;
*target = new char[charlen(source)+1];
copyon(*target, source);
return;
}
void anotherAssign(char* target, const char* source)
{
if (target==source)
return;
delete [] target;
target = new char[charlen(source)+1];
copyon(target, source);
return;
}
void copyon(char* const target, const char* const source)
{
char * t = target;
const char * s = source;
while (*t++ = *s++);
//while(*target++ = *source++)
// ;
std::cout << target << " source = " << source << std::endl;
return;
size_t len = charlen(source);
//for (size_t i=0; i<len; ++i)
// target[i]=source[i];
//target[len]='\0';
}
Here is an exception:
If you do:
char * test1 = new char[26];
then your array will go from test1[0] to test1[25].
That means:
test1[26] = '\0';
is out of bounds. At this point, the head is corrupted, and what happens next is undefined (but rarely desirable).
Basically what the title says. I have been trying to write my own string class using only char arrays and, while my code works when I run it in Visual Studio, I have trouble with it when using gcc .The problem seems to be coming when i try to delete in my getData function(can be seen below) The exception I get is:
Exception thrown at 0x6262436B (ucrtbased.dll) in string.exe: 0xC0000005: Access violation reading location 0xCCCCCCBC. occurred
My code :
Header:
#pragma warning(disable:4996)
#ifndef STRING_STRING_H
#define STRING_STRING_H
#include<iostream>
#include<cstring>
#include<fstream>
class String {
private:
char *data; //holds the text
size_t maxSize; //maximum number of chars in data
size_t currentSize; //current number of chars in data
void getData(const char *, size_t maxSize); //sets currentSize to the other char* size and
// copies the content of the other char* to data
public:
String(); //default constructor
~String(); //destructor
String(const String &); //copy-constructor(from String)
String(const char *); //copy-constructor(from char*)
String operator=(const String &); //operator= (from string)
String operator=(const char *); //operator=(from char*)
size_t length() const; //currentSize getter
void addChar(const char); //adds a char to the data array
void getLine(std::ifstream&,const char); // reads line till deliminator and stores it in this string object(all data previously stored is lost)
size_t find(const char*); //searches for text in the string and if found returns the starting position , if not found returns -1;
void print() const; //prints the string object to console
char* toChar() const; //returns a new allocated char pointer with the text inside (must be deleted afterwards)
};
#endif //STRING_STRING_H
cpp:
#include "String.h"
String::String() {
currentSize = 0;
maxSize = 16;
try {
data = new char[maxSize];
data[0] = '\0';
}
catch (std::bad_alloc &) {
std::cerr << "Not enough memory" << std::endl;
throw;
}
}
String::~String() {
delete[] data;
}
size_t String::length() const {
return currentSize;
}
String::String(const String &other) {
this->maxSize = other.maxSize;
getData(other.data, maxSize);
}
String::String(const char *other) {
this->maxSize = strlen(other) *2;
getData(other, maxSize);
}
void String::getData(const char *dataSource, size_t maxSize) {
currentSize = strlen(dataSource);
try {
char *newData = new char[maxSize];
delete[] data;
data = newData;
strcpy(data, dataSource);
}
catch (std::bad_alloc &) {
std::cerr << "Not enough memory" << std::endl;
throw;
}
}
String String::operator=(const String &other) {
if (this != &other) {
maxSize = other.maxSize;
getData(other.data, maxSize);
}
return *this;
}
String String::operator=(const char *other) {
if (this->data != other) {
maxSize = strlen(other) *2;
getData(other, maxSize);
}
return *this;
}
void String::addChar(const char newChar) {
if (maxSize == currentSize+1) {
maxSize *= 2;
getData(this->data, maxSize);
}
data[currentSize++] = newChar;
}
void String::getLine(std::ifstream & is, const char delim='\n')
{
char temp;
while (!is.eof())
{
is.get(temp);
if (temp == delim)
break;
else
addChar(temp);
}
return;
}
size_t String::find(const char * text)
{
size_t currPos=-1;
bool found = 0;
for (size_t i = 0; i < currentSize; i++)
{
if (data[i] == text[0])
{
for (size_t j = i+1; j < currentSize; j++)
{
if (data[j] == text[j - i])
found = 1;
else
{
found = 0;
break;
}
}
if (found == 1)
{
currPos = i;
break;
}
}
}
return currPos;
}
void String::print() const
{
for (size_t i = 0; i < currentSize; i++)
{
std::cout << data[i];
}
std::cout << std::endl;
}
char * String::toChar() const
{
char* text= new char[currentSize+1];
for (size_t i = 0; i < currentSize; i++)
{
text[i] = data[i];
}
text[currentSize + 1] = 0;
return text;
}
Your problem is caused by calling delete [] on uninitialized memory.
In the copy constructor, the data member is not initialized before calling getData(). In getData(), you are using delete [] data;.
You could initialize data to nullptr in the constructors to avoid the problem.
It's always a good idea to initialize all variables to some sensible value before the body of the constructor. E.g. you can implement the copy constructor as:
String::String(const String &other) : currentSize(0),
maxSize(other.maxSize),
data(nullptr)
{
getData(other.data, maxSize);
}
Similarly, implement the constructor from char const* as:
String::String(const char *other) : currentSize(0),
maxSize(strlen(other) *2),
data(nullptr)
{
getData(other, maxSize);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
/Unhandled exception at 0x00AB6591 in Building.exe: 0xC0000005: Access violation reading location 0x00000000./
#pragma warning (disable : 4996)
#include<iostream>
#include<string>
#include<cassert>
using namespace std;
class Building
{
private:
int height;
int area;
char*address;
public:
Building();
Building(int, int, char*);
~Building();
Building(const Building &);
Building & operator=(const Building&);
int getHeight()const;
int getArea()const;
char* getAddress()const;
void print()const;
void setHeight(int);
void setArea(int);
void setAddress(char*);
};
Building::Building()
{
height = 0;
area = 0;
address = new char[1];
address = NULL;
}
Building::Building(int h, int ar, char* a)
{
height = h;
area = ar;
address = new char[strlen(a)+1];
assert(address != NULL);
address = NULL;
}
Building::~Building()
{
delete[]address;
}
Building::Building(const Building & b)
{
height = b.height;
area = b.area;
address = new char[strlen(b.address) + 1];
assert(address != NULL);
strcpy(address,b.address);
}
Building & Building::operator=(const Building& b)
{
if (this != &b)
{
delete[]address;
height = b.height;
area = b.area;
address = new char[strlen(b.address) + 1];
assert(address != NULL);
strcpy(address, b.address);
}
return *this;
}
int Building::getHeight()const
{
return height;
}
int Building::getArea()const
{
return area;
}
char* Building::getAddress()const
{
return address;
}
void Building::print()const
{
cout << "Height = " << getHeight() << endl << "Area = " << getArea() << endl << "Address = " << getAddress() << endl;
}
void Building::setHeight(int h)
{
height = h;
}
void Building::setArea(int ar)
{
area = ar;
}
void Building::setAddress(char* adr)
{
strcpy(address, adr);
}
//==========================================================================================================
class House :public Building
{
private:
int floors;
char*name;
public:
House();
House(int,int,char*,int=0, char* =" ");
~House();
House(const House&);
House& operator=(const House&);
int getFloors()const;
char* getName()const;
void setFloors(int);
void setName(char*);
void print()const;
};
House::House()
{
floors = 0;
name = new char[1];
assert(name != NULL);
name = NULL;
}
House::House(int h, int ar, char* adr, int f, char* n) :Building(h, ar, adr)
{
floors = f;
name = new char[strlen(n) + 1];
assert(name != NULL);
strcpy(name, n);
}
House::~House()
{
delete[]name;
}
House::House(const House& h) :Building(h)
{
floors = h.floors;
name = new char[strlen(h.name) + 1];
assert(name != NULL);
strcpy(name, h.name);
}
House& House::operator=(const House&h)
{
if (this != NULL)
{
Building::operator=(h);
delete[]name;
floors = h.floors;
name = new char[strlen(h.name) + 1];
assert(name != NULL);
strcpy(name, h.name);
}
return*this;
}
int House::getFloors()const
{
return floors;
}
char* House::getName()const
{
return name;
}
void House::setFloors(int f)
{
floors = f;
}
void House::setName(char* na)
{
strcpy(name, na);
}
void House::print()const
{
Building::print();
cout << "Floors: " << getFloors() << endl << "Name: " << getName() << endl;
}
//=============================================================================================================
House getBigger(House m[], int size)// a house with bigger avarage height of a floor
{
House temp;
int max = 0;
int index = 0;
for (int i = 0; i < size; i++)
{
int avH = (m[i].getHeight() / m[i].getFloors());
if (avH >= max)
{
max = avH;
index = i;
}
}
return m[index];
}
//=============================================================================================================
int main()
{
House h1(16,400,"Bla street",4,"Marion");
h1.print();
House h2;
h2.setHouse();
h2.print();
House h3;
h3.setHouse();
h3.print();
House arr[] = { h1, h2, h3 };
House h4;
h4=getBigger(arr, 3);
h4.print();
system("pause");
return 0;
}
I have problem with my program for building and a house. It is simple maybe but I don't know why throws exception. I think that my try for user input is wrong anywhere.
Your Building constructors both set address to null. If you are trying to print the address anywhere, your code will give you that error.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Here is the function in question:
#include <cstdlib>
#include <string>
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include "Train.h"
#include "Platform.h"
const int NUM_TRAINS = 4;
const int NUM_NORTHERNLY_TRAINS = NUM_TRAINS / 2;
const int NUM_SOUTHERNLY_TRAINS = NUM_TRAINS - NUM_NORTHERNLY_TRAINS;
const int NUM_LOOPS = 16;
const char* TRAIN_NAME_ARRAY[NUM_TRAINS]
= { "Thomas the Tank-Engine",
"Percy the Small Engine",
"California Zephyr",
"Tokaido Shinkansen"
};
const int TRAIN_TRANSIT_TIME_MSECS[NUM_TRAINS]
= { 10000, // Thomas
10000, // Percy
5000, // CA Zephyr
1000 // Bullet train
};
Platform northBoundPlatform("North-bound Platform");
Platform southBoundPlatform("South-bound Platform");
void* initiallyNorthernly (void* vPtr)
{
Train* id = ((Train*)vPtr);
for (int i = 0; i < NUM_LOOPS; i++)
{
northBoundPlatform.arrive(id);
northBoundPlatform.leave();
pause();
southBoundPlatform.arrive(id);
southBoundPlatform.leave();
pause();
}
return((void*)id);
}
void* initiallySouthernly (void* vPtr)
{
Train* id = (Train*)vPtr;
for (int i = 0; i < NUM_LOOPS; i++)
{
southBoundPlatform.arrive(id);
southBoundPlatform.leave();
pause();
northBoundPlatform.arrive(id);
northBoundPlatform.leave();
pause();
}
return((void*)id);
}
int main ()
{
pthread_t tidArray[NUM_TRAINS];
Train* trainArray[NUM_TRAINS];
pthread_t tidArray2[NUM_NORTHERNLY_TRAINS];
Train* trainArray2[NUM_NORTHERNLY_TRAINS];
pthread_t tidArray3[NUM_SOUTHERNLY_TRAINS];
Train* trainArray3[NUM_SOUTHERNLY_TRAINS];
for (int i = 0; i < NUM_TRAINS; i++)
{ trainArray[i] = new Train(TRAIN_NAME_ARRAY[i],TRAIN_TRANSIT_TIME_MSECS[i]);
}
int trainInd = 0;
for (int i = 0; i < NUM_NORTHERNLY_TRAINS; i++)
{
pthread_create(&tidArray2[i], NULL, initiallyNorthernly,&trainArray2[i]);
}
for (int i = 0; i < NUM_SOUTHERNLY_TRAINS; i++)
{
pthread_create(&tidArray3[i], NULL, initiallySouthernly,&trainArray3[i]);
}
for (int i = 0; i < NUM_TRAINS; i++)
{
trainArray[i] = NULL;
// Wait for all Train threads. Also, get the pointers to the Train objects
// and delete() them because they were created by 'new'
pthread_join(tidArray[i], (void**)&trainInd);
pthread_join(tidArray2[i],(void**)&trainInd);
pthread_join(tidArray3[i],(void**)&trainInd);
}
return(EXIT_SUCCESS);
}
Here are the appropriate header files:
Train.h
class Train
{
std::string name_;
int pauseTimeUsecs_;
public :
Train (const std::string& newName,
int newPauseTimeUsecs
)
{
name_ = newName;
pauseTimeUsecs_ = newPauseTimeUsecs;
std::cout << getName() << " leaving the trainyard.\n";
}
~Train ()
{
std::cout << getName() << " going back to the trainyard\n";
}
const std::string&
getName ()
const
{ return(name_); }
void pause ()
const
{
usleep(pauseTimeUsecs_);
}
};
Platform.h
class Platform
{
std::string name_;
Train* trainPtr_;
pthread_mutex_t mutexLock_;
pthread_cond_t notEmptyCond_;
pthread_cond_t notFullCond_;
public :
Platform (const std::string& newName
)
{
name_ = newName;
trainPtr_ = NULL;
pthread_mutex_init(&mutexLock_,NULL);
pthread_cond_init(¬EmptyCond_,NULL);
pthread_cond_init(¬FullCond_,NULL);
}
// PURPOSE: To release resources. No parameters. No return value.
~Platform ()
{
pthread_mutex_destroy(&mutexLock_);
pthread_cond_destroy(¬EmptyCond_);
pthread_cond_destroy(¬FullCond_);
}
const std::string&
getName ()
const
{
return(name_);
}
Train* getTrainPtr
()
const
{
return(trainPtr_);
}
void arrive (Train* newTrainPtr
)
{
pthread_mutex_lock(&mutexLock_);
while (getTrainPtr() != NULL)
{
std::cout << getTrainPtr()->getName()
<< " is at " << getName()
<< ", " << newTrainPtr->getName()
<< " must wait.\n";
usleep(10) + rand() % 10;
pthread_cond_wait(¬FullCond_,&mutexLock_);
}
std::cout << newTrainPtr->getName() << " arriving at " << getName() << "\n";
trainPtr_ = newTrainPtr;
usleep(10 + rand() % 10);
pthread_mutex_unlock(&mutexLock_);
pthread_cond_signal(¬EmptyCond_);
}
Train* leave ()
{
pthread_mutex_lock(&mutexLock_);
while (getTrainPtr() == NULL)
{
std::cout << "No train at " << getName() << "!\n";
usleep(10 + rand() % 10);
pthread_cond_wait(¬EmptyCond_,&mutexLock_);
}
Train* toReturn = getTrainPtr();
std::cout << toReturn->getName() << " leaving " << getName() << "\n";
usleep(10 + rand() % 10);
trainPtr_ = NULL;
pthread_cond_signal(¬FullCond_);
pthread_mutex_unlock(&mutexLock_);
return(toReturn);
}
};
After running with gdb, the segmentation fault is occurring when I call arrive on northBoundPlatform(a Platform object). The goal of the function is to make the train object that is pointed to by vPtr arrive() at northernPlatform, leave() at northernPlatform, pause() on the train object, arrive() at the southBoundPlatform, leave() the southBoundPlatform, pause() on the object again, and finally return a pointer to the train that was used.
I am not sure if I am casting vPtr into a Train* correctly which is causing a segmentation fault. I can provide the rest of the main code if necessary. Any help is appreciated.
Your main() function has two for loops for each of NUM_NORTHERNLY_TRAINS, using initiallyNorthernly and initiallySouthernly, but the second loop should be looping with NUM_SOUTHERNLY_TRAINS instead.