Here's my main in Airport.cpp:
#include <iostream>
#include "Airport_Queue.h"
#include "Airplane.h"
#include <stdlib.h>
int main(){
Airplane *b = new Airplane(true);
(*b).come();
(*b).go();
std::cout << "........." << std::endl;
Airport_Queue *landing_queue = new Airport_Queue(5);
Airplane *a0 = new Airplane(true);
(*landing_queue).enqueue(a0); //error here
//(*landing_queue).dequeue();
return 0;
This is my Airport_Queue.cpp
#include "Airport_Queue.h"
Airport_Queue::Airport_Queue(unsigned n){
Airplane** a = new Airplane*[n];
capacity = n;
size = 0;
head = tail = 0;
}
Airport_Queue::~Airport_Queue(){
for (size_t i = 0; i < size; i++){
delete a[i];
}
delete [] a;
}
void Airport_Queue::enqueue(Airplane* airplane){
if (!(*this).isFull()){
a[tail] = airplane;
(*a[tail]).come();
tail = (tail+1) % capacity;
size++;
}
else{
std::cerr << "Queue is full." << std::endl;
}
}
Airplane* Airport_Queue::dequeue(){
if (!(*this).isEmpty()){
size_t x = head;
(*a[head]).go();
head = (head+1) % capacity;
size--;
return a[x];
}
else{
std::cerr << "Queue is empty." << std::endl;
return NULL;
}
}
bool Airport_Queue::isEmpty(){
if (size == 0)
return true;
else
return false;
}
bool Airport_Queue::isFull(){
if (size == capacity)
return true;
else
return false;
}
int Airport_Queue::getSize(){
return size;
}
I also have a class called Airplane. The command I use to compile and link is
g++ -std=c+11 -Wall -g -o airport Airport.cpp Airplane.cpp Airport_Queue.cpp
How can I fix this run-time error? The error is when I call enqueue. Then I get
4 [main] airport 3796 cygwin_exception::open_stackdumpfile: Dumping stack trace to airport.exe.stackdump
Please. And thank you.
Problems I see:
You have one member variable size. You need two - capacity and size.
In Airport_Queue::Airport_Queue
Airport_Queue::Airport_Queue(unsigned size){
Airplane** a = new Airplane*[size];
size = 0; // This is the argument, not the member variable.
// The member variable remains uninitialized.
head = tail = 0;
}
You need:
Airport_Queue::Airport_Queue(unsigned size){
Airplane** a = new Airplane*[size];
this->capacity = size;
this->size = 0;
head = tail = 0;
}
In Airport_Queue::~Airport_Queue
Airport_Queue::~Airport_Queue(){
for (size_t i = 0; i < sizeof(a); i++){
// sizeof(a) does not give you the number of elements
// in the array. It just gives you the size of the pointer.
delete a[i];
}
delete [] a;
}
You need:
Airport_Queue::~Airport_Queue(){
for (size_t i = 0; i < this->size; i++){
delete a[i];
}
delete [] a;
}
In Airport_Queue::enqueue
Following on the logic from the destructor, the following line needs to be changed.
tail = (tail+1) % sizeof(a);
Change it to:
tail = (tail+1) % capacity;
In In Airport_Queue::dequeue
You have an error similar to the above. Change the line
head = (head+1) % sizeof(a);
to
head = (head+1) % capacity;
In Airport_Queue::isFull
Change the line
if (size == sizeof(a))
to
if (size == capacity)
I hope this fixes most of your problems. If there are any that I missed, hopefully you can find them.
Related
I tried to implement tower of hanoi using stack but there seems to be some problem when running the program. It runs fine sometimes but sometimes the program terminates.
I created a separate class to work as stack.
class stack{
int* arr;
int stackSize;
public:
stack(int size = 0);
~stack();
void push(int a);
int pop();
};
stack::stack(int size){
this->arr = new int(size);
this->stackSize = 0;
}
stack::~stack(){
delete []this->arr;
}
void stack::push(int a){
this->stackSize++;
int* temp = new int(this->stackSize);
for(int i = 0; i < this->stackSize; i++){
temp[i] = this->arr[i];
}
temp[this->stackSize-1] = a;
delete []this->arr;
this->arr = temp;
}
int stack::pop(){
if(this->stackSize <= 0){
cout << "stack underflow" << endl;
}else{
this->stackSize--;
int popped = this->arr[this->stackSize];
int* temp = new int(this->stackSize);
for(int i = 0; i < this->stackSize; i++) {
temp[i] = this->arr[i];
}
delete []this->arr;
this->arr = temp;
return popped;
}
}
void toh(int n, stack &s, stack &des, stack &aux){
if (n <= 0)
return;
toh(n-1, s, aux, des);
des.push(s.pop());
display();
toh(n-1, aux, des, s);
}
this->arr = new int(size); does not allocate memory for an array, it allocates for a single integer. You want this->arr = new int[size]; you do similar in your push function too.
Also, to add, your push should only allocate a new array when it is full.
Also also, in pop, you do not return a value in the case when the if is true. Should either throw an exception, or return a dummy value.
This assignment (I've linked the full description here) asks us to create a multi server queue simulation (i.e. grocery store type scenario). My code seems to be working for the most part however I currently have 2 questions pertaining to my output that I am having a hard time answering.
Why does queue_total not match the actual number of elements displayed in each queue at the end of the program?
Why won't new items be enqueued to the shortest queue even though the shortest_queue function seems to be working?
The main code:
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
#include "queue_2.h"
using namespace std;
// Utility function to return shortest queue.
int shortest_queue(Queue line[], int queuecount)
{
int shortest = 0;
// Condition 1: If a queue is empty
// with no active transactions, return it.
for (int i = 0; i < queuecount; i++) {
if (line[i].empty() && line[i].get_trans_time() == 0)
return i;
}
// Condition 2: If a queue is simply empty,
// return it next.
for (int i = 0; i < queuecount; i++) {
if(line[i].empty()) {
return i;
}
}
// Condition 3: (otherwise) If all queues are
// occupied check for shortest queue.
for (int i = 1; i < queuecount; i++) {
if(line[i].size() < line[shortest].size())
shortest = i;
}
return shortest;
}
// Utility function to return total number
// of customers waiting in queues.
int queue_total(Queue q[], int queuecount)
{
int custcount = 0;
for (int i = 0; i < queuecount; ++i)
custcount += q[i].size();
return custcount;
}
int main()
{
// Variable decelrations
int trans_time = 0;
int count = 0;
int entry_time;
int wait_sum = 0;
int wait_time = 0;
int seed = 3;
int ariv_prob = 80;
int MAX_TRANS_TIME = 12;
int DURATION = 120;
int queuecount = 4;
int shortline;
int temp;
// Create a list of queues
// and random number generator
Queue line[queuecount];
srand(seed);
for (int time = 1; time < DURATION + 1; time++)
{
// Display the time
cout << "Time: " << time << endl;
// Check probablity only once per iteration
if ( rand() % 100 < ariv_prob ) {
shortline = shortest_queue(line, queuecount);
line[shortline].enqueue(time);
}
// Update the transaction times for
// the corresponding queues and compute
// summary statistics.
for (int i = 0; i < queuecount; i++) {
if ( line[i].get_trans_time() == 0 ) {
if ( !line[i].empty() ) {
entry_time = line[i].print_front();
line[i].dequeue();
temp = (time - entry_time);
if(temp > wait_time)
wait_time = temp;
wait_sum += (time - entry_time);
++count;
line[i].set_trans_time((rand() % MAX_TRANS_TIME) + 1);
}
}
// Decrement and update transaction time.
else {
trans_time = line[i].get_trans_time() - 1;
line[i].set_trans_time(trans_time);
}
}
// Display status of the queues for the
// the given iteration.
for (int i = 0; i < queuecount; i++) {
cout << setw(4) << line[i].get_trans_time() << " ";
line[i].display();
}
cout << endl;
}
cout << count << " customers waited an average of ";
cout << wait_sum / count << " ticks." << endl;
cout << "The longest time a customer waited was " << wait_time << " ticks." << endl;
cout << queue_total(line, queuecount) << " customers remain in the lines." << endl;
return 0;
}
The queue implementation
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
using namespace std;
class Queue {
private:
struct Node {
int data;
Node* next;
Node(int d) {
data = d;
next = NULL;
}
};
Node* front;
Node* rear;
int count;
int trans_time;
public:
Queue() {
front = rear = NULL;
count = trans_time = 0;
}
void enqueue(int x) {
// Create a new linked Node.
Node* temp = new Node(x);
// If the queue is already empty
// then new node is front and rear
if (empty()) {
front = rear = temp;
return;
}
// Add the new node at the end
// of the queue and change the rear
rear->next = temp;
rear = temp;
++count;
}
void dequeue() {
// If the queue is empty
// then we can return NULL
if (empty())
return;
// Store the previous front and
// move the front one node ahead
Node* temp = front;
front = front->next;
// If front becomes NULL, then
// Change the rear to be NULL as well
if (front == NULL)
rear = NULL;
delete(temp);
--count;
}
// Utility function to check
// if the queue is empty
bool empty() {
return (front == NULL && rear == NULL);
}
int size() {
return count;
}
// Utility function to print front
// element of the queue
int print_front() {
return front->data;
}
void display() {
Node* temp = front;
while (!(temp == NULL)) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
void set_trans_time(int i) {
trans_time = i;
}
int get_trans_time() {
return trans_time;
}
};
#endif
Your enqueue function doesn't increment (or set) the count when inserting into an empty queue. This causes the count to be 0 for a queue with 1 element.
The comparisons for count > 0 or count >= 0 before decrementing/incrementing it should be unnecessary. If those conditions are ever false then you have a problem elsewhere that caused the inconsistency.
I was doing a code in which I have to create a dynamic array and a pointer (the pointer should be used to move through the data of the array). I have to make methods get (to return the index of a number to be searched in the array), update (when get method returns the index the update method can update the value), length(this method should return the size of the array), next(this method should move the pointer to the next index of the array), start(this method should move the pointer to the start of the array), end(this method should move pointer to the end of array) and Add(it should add a block to the array)
Here is the code
#include <iostream>
#include <conio.h>
using namespace std;
class Runner
{
private:
int *arr;
int *ptr;
int size;
// to input in array
void Input()
{
for (int i = 0; i < size; i++,*ptr++)
{
cout << "Enter value no. " << i + 1 << "\t";
cin >> arr[i];
}
}
//to allocate memory
void Create()
{
cout << "Enter the total number of elements :\t";
cin >> size;
arr = new int[size];
ptr = arr;
Input();
}
public:
//constructor to define starting value
Runner()
{
ptr = NULL;
size = 0;
arr = NULL;
}
//get function
int get(int num)
{
bool NotNull = false;
int index = 0;
do
{
if (ptr != NULL)
{
ptr = &arr[0];
for (int i = 0; i < size; i++,*(ptr++))
{
if (num == *ptr)
{
index = i;
break;
}
}
NotNull = true;
}
else
{
Create();
}
} while (!NotNull);
return index;
}
//update function
void Update(int num)
{
int val;
int index = get(num);
cout << "Enter value to update :\t";
cin >> val;
ptr = ptr + index;
*ptr = val;
}
//length function
int length()
{
if (ptr == NULL)
{
Create();
}
return size;
}
//moving pointer back
void Back()
{
bool NotNull = false;
do
{
if (ptr != NULL)
{
*(ptr--);
NotNull = true;
}
else
{
Create();
}
} while (!NotNull);
}
//moving pointer forward;
void Next()
{
bool NotNull = false;
do
{
if (ptr != NULL)
{
*(ptr++);
NotNull = true;
}
else
{
Create();
}
} while (!NotNull);
}
//to point at the start of array
void Start()
{
bool NotNull = false;
do
{
if (ptr != NULL)
{
ptr = &arr[0];
NotNull = true;
}
else
{
Create();
}
} while (!NotNull);
}
//to move pointer to the end
void End()
{
bool NotNull = false;
do
{
if (ptr != NULL)
{
ptr = &arr[size - 1];
NotNull = true;
}
else
{
Create();
}
} while (!NotNull);
}
//to add a block into array
void Add()
{
int NewSize = size + 1;
int *temp = new int[NewSize];
for (int i = 0; i < size; i++)
{
temp[i] = arr[i];
}
size = NewSize;
ptr = temp;
if (arr != NULL)
{
delete[] arr;
}
arr = NULL;
arr = temp;
cout << "You have been provided a new block to add 1 data entry\n";
cout << "Enter value :\t";
cin >> arr[size - 1];
}
};
int main() //main made just for testing above method's working
{
Runner *obj = new Runner();
obj->get(3);
obj->Update(20);
cout << obj->length() << "\n";
obj->Next();
obj->End();
obj->Back();
obj->Start();
obj->Add();
delete obj;
_getch();
return 0;
}
Well the part of code giving me error is the Add method in which i have to increase the size of array without using realloc().
The Add Method is as follows:
void Add()
{
int NewSize = size + 1;
int *temp = new int[NewSize];
for (int i = 0; i < size; i++)
{
temp[i] = arr[i];
}
size = NewSize;
ptr = temp;
if (arr != NULL)
{
delete[] arr; //the point where heap corruption error occurred
}
arr = NULL;
arr = temp;
cout << "You have been provided a new block to add 1 data entry\n";
cout << "Enter value :\t";
cin >> arr[size - 1];
}
Help me in solving this issue.
The last two statements in Update
ptr = ptr + index;
*ptr = val;
will set pointer to some value relative to the last value, which was set in the preceding call to get. This will cause ptr to refer to memory beyond the allocated space for arr if the value was found in the second half of the array. When you assign the value with *ptr = val; you are at best writing to the wrong array element, at worst writing to memory you don't own. The "Heap Corruption" error detects this.
The solution would be to set ptr using arr instead:
ptr = arr + index;
since ptr may point past the end of the allocated space if the number was not found (and index would be 0).
I have a HashTable class. The purpose of this is to practice how to produce Hash Table. My current issue right now is the destructor. I should be seeing on the console, this:
But instead i see this:
I've ran gdb ./app which gives me this:
#include <iostream>
#include "HashTable.h"
using namespace std;
int main(){
HashTable table;
table.initTable();
table.addNode("Software");
table.addNode("Engineering");
table.addNode("Art");
table.addNode("Programming");
table.addNode("Miscellanous");
table.displayByIndex();
return 0;
}
HashTable Header:
#ifndef _HASHTABLE_H_
#define _HASHTABLE_H_
#include <iostream>
#include "Hash.h"
class HashTable{
private:
static const int TABLESIZE = 5;
Hash* head;
public:
HashTable();
~HashTable();
void initTable();
int hashKey(char*);
int quadProbing(int,int);
int hashKeyWithProbing(char*);
bool isEmpty();
void addNode(char*);
void displayByIndex();
void searchByKey(char*);
};#endif
Here it my Hash Table CPP, i included the Constructor/Destructor and init functions. The other functions arent included since i dont utilize the 'new' keyword. If its needed i will include it [hope to make this thread small]
#include "HashTable.h"
#include <cstring>
HashTable::HashTable(){
head = new Hash[TABLESIZE];
}
HashTable::~HashTable(){
Hash* destList = NULL;
for(int i = 0; i< TABLESIZE; i++){
destList = &head[i];
while(destList != NULL){
head = head->getNext();
delete destList;
destList = head;
}
}
head = NULL;
delete [] head;
}
void HashTable::initTable(){
for(int i = 0; i < TABLESIZE; i++){
Hash *traverseHeadArray = &head[i];
traverseHeadArray->setKey("EMPTY");
traverseHeadArray->setNext(NULL);
traverseHeadArray = NULL;
}
}
int HashTable::hashKey(char *tempKey){
//Find the asc value for the string
//add them together
//modules by the total table size
//then return the index (remainder using modules)
//Index is were that key will be stored
int index = 0;
for(int i = 0; i < strlen(tempKey); i++){
index += tempKey[i];
}
return index % TABLESIZE;
}//DONE
int HashTable::quadProbing(int index, int counter){
return (index + counter*counter) % TABLESIZE;
}//DONE
int HashTable::hashKeyWithProbing(char* key){
int index = hashKey(key);
int count = 1;
while(head[index].getKey() != key && head[index].getKey() != "EMPTY"){
index = quadProbing(index, count);
count++;
}
return index;
}//DONE
void HashTable::addNode(char* tempValue){
Hash* newNode = new Hash;
newNode->setKey(tempValue);
newNode->setNext(NULL);
int index = hashKey(tempValue);
int counter = 1;
while(head[index].getKey() != tempValue && head[index].getKey() !="EMPTY")
{
index = quadProbing(index, counter);
counter++;
}
Hash* traverse = &head[index];
if(isEmpty() || traverse->getKey() == "EMPTY"){
traverse->setKey(newNode->getKey());
traverse->setNext(newNode->getNext());
}else{
while(traverse->getNext() != NULL)
traverse = traverse->getNext();
traverse->setNext(newNode);
}
traverse = NULL;
delete newNode;
}
void HashTable::displayByIndex(){
for(int i = 0; i < TABLESIZE; i++){
Hash *traverse = &head[i];
std::cout << "----------------------------------------" << std::endl;
std::cout << "INDEX: " << i << std::endl;
while(traverse != NULL){
std::cout << "Key: " << traverse->getKey() << std::endl;
traverse = traverse->getNext();
}
std::cout << "----------------------------------------" << std::endl;
traverse = NULL;
}
}
bool HashTable::isEmpty(){
return (head == NULL);
}
void HashTable::searchByKey(char* key){
int index = hashKeyWithProbing(key);
if(isEmpty())
std::cout << "Empty Bucket\n";
else{
Hash* traverse = &head[index];
while(traverse != NULL && traverse->getKey() != "EMPTY"){
std::cout << "TOPIC KEY: " << traverse->getKey() << std::endl;
traverse = traverse->getNext();
}
traverse = NULL;
}
}
Here is my Hash Class header and CPP files:
#ifndef _HASH_H_
#define _HASH_H_
class Hash{
private:
char* key;
Hash* next;
public:
Hash();
~Hash();
void setKey(char*);
void setNext(Hash* const);
char* getKey();
Hash* getNext();
};#endif
#include "Hash.h"
#include <iostream>
Hash::Hash(){
key = NULL;
next = NULL;
}
Hash::~Hash(){
// TODO Destructor
}
void Hash::setKey(char* tempKey){
this->key = tempKey;
}
void Hash::setNext(Hash* const tempNext){
this->next = tempNext;
}
char* Hash::getKey(){
return key;
}
Hash* Hash::getNext(){
return next;
}
In your code, you allocating only the getNext() nodes,
so you should delete only them, (you tried to delete &head[i] which wasn't allocated at all).
There is still an exception for double freeing some node, you should debug and follow the stack for figuring it out.
HashTable::~HashTable(){
for(int i = 0; i< TABLE_SIZE; i++){
Hash* node = head[i].getNext();
while(node != nullptr){
Hash* temp = nullptr;
if (node -> getNext()) {
temp = node->getNext();
}
delete node;
node= temp;
}
}
delete[] head;
}
Output:
----------------------------------------
INDEX: 0
Key: Art
----------------------------------------
----------------------------------------
INDEX: 1
Key: Engineering
----------------------------------------
----------------------------------------
INDEX: 2
Key: Miscellanous
----------------------------------------
----------------------------------------
INDEX: 3
Key: Software
----------------------------------------
----------------------------------------
INDEX: 4
Key: Programming
----------------------------------------
double free or corruption (fasttop)
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
I am using linked lists to simulate a computer lab, and I am trying to print the linked lists. There's an issue with printing using cout, it produces garbage until the terminal just gives up and sends a segmentation fault 11.
#include <iostream>
#include <string>
using namespace std;
struct lab {
string current_ID;
int station_number;
lab *link;
};
typedef lab* lab_ptr;
void print_status(lab_ptr& head1, lab_ptr& head2, lab_ptr& head3, lab_ptr& head4);
int main()
{
lab_ptr head_lab_1;
head_lab_1 = new lab;
lab_ptr head_lab_2;
head_lab_2 = new lab;
lab_ptr head_lab_3;
head_lab_3 = new lab;
lab_ptr head_lab_4;
head_lab_4 = new lab;
set_up_linked_list_for_n_stations(head_lab_1, 5);
set_up_linked_list_for_n_stations(head_lab_2, 6);
set_up_linked_list_for_n_stations(head_lab_3, 4);
set_up_linked_list_for_n_stations(head_lab_4, 3);
return 0;
}
void set_up_linked_list_for_n_stations(lab_ptr& head, int n)
{
lab_ptr curr;
curr = new lab;
for(int j = 0; j < n; j++)
{
lab_ptr temp = new lab;
temp->link = NULL;
temp->station_number = n+1;
temp->current_ID = 'empty';
cout << temp->station_number << " " << temp->current_ID << endl;
if(head != NULL)
{
curr = head;
while(curr->link != NULL)
{
curr = curr->link;
}
curr->link = temp;
} else
{
head = temp;
}
}
}
This is literally my first time using linked lists, so the error can be something incredibly obvious that i just missed. Sorry for advanced if it's a dumb mistake.
For the string member current_ID you need to pass the value using double quotes:
temp->current_ID = 'empty';
becomes
temp->current_ID = "empty";
Also you need to move the function void set_up_linked_list_for_n_stations(lab_ptr& head, int n) before the main()
You are making extra allocations, other place the list is not properly initialized. Initialize head_lab_1 to nullptr (or just NULL)
In the function set_up_linked_list_for_n_stations remove curr = new lab
void set_up_linked_list_for_n_stations(lab_ptr& head, int n)
{
for(int j = 0; j < n; j++)
{
lab_ptr temp = new lab;
temp->link = NULL;
temp->station_number = n + 1;
temp->current_ID = "empty";
cout << temp->station_number << " " << temp->current_ID << endl;
if(head != NULL)
{
lab_ptr curr = head;
while(curr->link != NULL)
{
curr = curr->link;
}
curr->link = temp;
}
else
{
head = temp;
}
}
}
int main()
{
lab_ptr head_lab_1 = nullptr;
lab_ptr head_lab_2 = nullptr;
lab_ptr head_lab_3 = nullptr;
lab_ptr head_lab_4 = nullptr;
set_up_linked_list_for_n_stations(head_lab_1, 5);
set_up_linked_list_for_n_stations(head_lab_2, 6);
set_up_linked_list_for_n_stations(head_lab_3, 4);
set_up_linked_list_for_n_stations(head_lab_4, 3);
return 0;
}