Click to See Complete Forum and Search --> : Help me debug my homework


qofcourse
March 8th, 2006, 12:55 AM
I've been trying for the last few hours to get my homework assignment to compile with no luck. There were a lot of errors I've successfully cleaned out, but there are also a lot that don't make any sense to me - g++ is telling me that variables passed into a function aren't declared in that scope, that "cout" is undeclared when I've already included iostream, that functions I just wrote can't be used as functions, etc etc. I'll admit it: I'm about as confused as I've ever been. I need help.

The objective of the assignment is to mimic a CPU scheduling system. As yet I have no idea if the program does what it's supposed to, but I can figure that out later. For now, I'd love some help getting this to run.

This program is the one you actually execute, which forks off the second program then reads commands from a file and pipes them to the second program. It compiles fine.


#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <iostream>
using namespace std;


int main(){
int filedes[2];
pid_t pid;
char* cmd;
char arg[8];

if (pipe(filedes) != 0){
perror("Failed to create pipe.");
exit(1);
}

if ((pid = fork()) == 0){
// this is the child process in here
snprintf(arg, 8, "%d", filedes[0]);
execl("manager", "manager", arg, NULL);
}

while(1){
cin >> cmd;
write(filedes[1], cmd, strlen(cmd));
sleep(1);
}
}


This is the meat of the program, which interprets and acts on the commands, and where I'm getting most of the compilation issues:


#include <iostream>
#include <queue>
#include <fstream>
#include <sys/types.h>
#include "queue_array.h"
using namespace std;

class ProgramArray{
public:
ProgramArray::ProgramArray (char readFrom, int pid, int ppid, int priority, int time);
ProgramArray::ProgramArray (char[] readFrom, int pid, int ppid, int priority, int time);


void setPid(int npid) { this->pid = npid; }
int getPid() { return this->pid; }

void setPPID(int nppid) { this->ppid = nppid; }
int getPpid() { return this->ppid; }

// progcounter is the number of instructions that have been done yet
void setProgCounter(int npcv) { *this->pcv = npcv; }
int* getProgCounter() { return this->pcv; }

void setData(int ndata) { this->data = ndata; }
int getData() { return this->data; }

void setPriority(int npriority) { this->priority = npriority; }
int getPriority() { return this->priority; }

void setState(char nstate) { this->state = nstate; }
char getState() { return this->state; }

void setStartTime(int nstart) { this->startTime = nstart; }
int getStartTime() { return this->startTime; }

void setTimeUsed(int ntime) { this->timeUsed = ntime; }
int getTimeUsed() { return this->timeUsed; }

void setCommands(char[] cmds) { this->commands = cmds; }
int getCommands() { return this->commands; }

private:
char[50] commands;
int pid;
int ppid;
int* pcv;
int data;
int priority;
char state;
int startTime;
int timeUsed;
}


class CPU{
public:
void incrementProgCounter() { progCounter++; }

ProgramArray* getCurrentlyExecuting() { return currentlyExecuting; }
void setCurrentlyExecuting(ProgramArray* novwi) { currentlyExecuting = novwi; }

int getProgCounter() { return progCounter; }
void setProgCounter(int novwi) { progCounter = novwi; }

int getData() { return data; }
void setData(int novwi) { data = novwi; }

int getTimeSlice() { return timeSlice; }
void setTimeSlice(int novwi) { timeSlice = novwi; }

private:
ProgramArray* currentlyExecuting;
int progCounter;
int data;
int timeSlice = 0;
}

void report(){
cout << "***************************************************" << endl;
cout << "Current system state is as follows:" << endl;
cout << "***************************************************" << endl;
cout << endl;
cout << "CURRENT TIME: " << endl;
cout << endl;
cout << "Running Process:" << endl;
cout << endl;
cout << endl;
cout << "BLOCKED PROCESSES:" << endl;
cout << "Queue of blocked processes:" << endl;
cout << endl;
cout << endl;
cout << "PROCESSES READY TO EXECUTE:" << endl;
cout << "Queue of processes with priority 0:" << endl;
cout << endl;
cout << "Queue of processes with priority 1:" << endl;
cout << endl;
cout << "Queue of processes with priority 2:" << endl;
cout << endl;
cout << "Queue of processes with priority 3:" << endl;
cout << endl;
}

ProgramArray* duplicateProcess(CPU* cpu, int pid, int time){
ProgramArray* dupedProc = new ProgramArray(cpu->getCurrentlyExecuting()->getCommands(), pid, cpu->getCurrentlyExecuting()->getPid(), cpu->getCurrentlyExecuting()->getPriority(), time);

dupedProc->setData(cpu->getCurrentlyExecuting()->getData());
dupedProc->setProgCounter(cpu->getProgCounter()+1);

return dupedProc;
}

ProgramArray::ProgramArray (char readFrom, int pid, int ppid, int priority, int time){
this->pid = pid;
char next;
this->ppid = ppid;
this->priority = priority;
this->startTime = time;
this->timeUsed = 0;

ifstream fin(readFrom);
while(fin >> next){
commands[commandCounter] = next;
commandCounter++;
}
fin.close();

}

ProgramArray::ProgramArray (char[] readFrom, int pid, int ppid, int priority, int time){
this->pid* = pid;
this->ppid* = ppid;
this->priority = priority;
this->commands* = readFrom*;
this->startTime = time;
this->timeUsed = 0;
}

void block(queue* blockedState, CPU* cpu){
cpu->getCurrentlyExecuting()->setData(cpu->getData());
cpu->getCurrentlyExecuting()->setProgCounter(cpu->getProgCounter());
cpu->getCurrentlyExecuting()->addTime(cpu->getTime());

blockedState->enque(cpu->getCurrentlyExecuting());

return;
}

void executeProc(queue_array* readyState, CPU* cpux){
ProgramArray* execMe;
readyState->Dequeue(execMe);

cpux->setData(execMe->getData());
cpux->setTimeSlice(0);
cpux->setProgCounter(execMe->getProgCounter());
cpux->setCurrentlyExecuting(execMe);

return;
}

int getQuanta(int priority){
switch (priority){
case 0: return 1;
case 1: return 2;
case 2: return 4;
case 3: return 8;
break;
}
return -1;
}

int main(int argc, char **argv){
int read_pipe = atoi(argv[1]);
char cmd;
pid_t pid;
int prog_counter = 0;

// Prescribed data structures begin here
int time = 0;
CPU* cpu;
ProgramArray pcbTable[50];
queue_array* readyState(4);
queue* blockedState;
int runningState;

// make the first sim process, then increment the # of counters
pcbTable[prog_counter] = newProcess('B', prog_counter++);

while(1){
read(read_fd, cmd, 1);

switch(cmd){
case 'Q': {
string int_interpreter = "";
string currentCommand = currentlyExecuting.getCommands[cpu->getProgCounter()];
cpu->incrementProgCounter();
int arg;

switch(currentCommand.c_str[0]){
case 'S':
for(i = 2; i < currentCommand.c_str.size(); i++){
int_interpreter += currentCommand.c_str[i];
}
cpu->setData(std::atoi(int_interpreter.c_str()));
break;
case 'A':
for(i = 2; i < currentCommand.c_str.length(); i++){
int_interpreter += currentCommand.c_str[i];
}
cpu->setData(cpu->getData()+std::atoi(int_interpreter.c_str()));
break;
case 'D':
for(i = 2; i < currentCommand.c_str.length(); i++){
int_interpreter += currentCommand.c_str[i];
}
cpu->setData(cpu->getData()-std::atoi(int_interpreter.c_str()));
break;
case 'B':
if (cpu->getCurrentlyExecuting()->getPriority() > 0){
cpu->getCurrentlyExecuting()->setPriority(cpu->getCurrentlyExecuting()->getPriority()-1);
}
block(blockedState, cpu);
executeProc(readyState, cpu);
break;
case 'E':
pcbTable[cpu->getCurrentlyExecuting()->getPid()] = null;
~(cpu->getCurrentlyExecuting());
executeProc(readyState, cpu);
break;
case 'F':{
ProgramArray* forked = duplicateProcess(cpu, prog_counter);
pcbTable[prog_counter] = forked&;
readyQueue.Enqueue(forked);
prog_counter++;

for(i = 2; i < currentCommand.c_str.length(); i++){
int_interpreter += currentCommand.c_str[i];
}
arg = std::atoi(int_interpreter);

cpu->setProgCounter(cpu->getProgCounter() + arg);
break;
}
case 'R':
char newProg = currentCommand.c_str[2], next;
char[50] newCmds;
int commandCounter;

cpu->setProgCounter(0);
cpu->setData(null);

ifstream fin(newProg);
while(fin >> next){
newCmds[commandCounter] = next;
commandCounter++;
}
fin.close();

cpu->getCurrentlyExecuting()->setCommands(newCmds);

break;

}

time++;
cpu->setTimeSlice(cpu->getTimeSlice()+1);
int currentPriority = cpu->getCurrentlyExecuting()->getPriority();
if (cpu->getTimeSlice() == getQuanta(currentPriority){
if (currentPriority < 3) { cpu->getCurrentlyExecuting->setPriority(currentPriority+1); }
block(blockedQueue, cpu);
executeProc(readyQueue, cpu);
}

break;
}

case 'U':
{
if (!blockedState->empty()){
ProgramArray ready = blockedState->deque();
readyState.Enqueue(ready, ready.getPriority());
}
}
break;

case 'P': if ((pid = fork()) == 0){ report(); exit(1); }
break;

case 'T': if ((pid = fork()) == 0){ report(); exit(1); }
exit(1);
break; // not exactly necessary, is it?

}
}
}


And finally, the queue_array.h data structure which gives the first handful of errors. This was written by the class TA, and several other students have said it works fine.


#ifndef _QUEUE_ARRAY_H_
#define _QUEUE_ARRAY_H_

#include <vector>

template <class type>
class QueueArray
{
private:
vector< vector< type > > _qarray;

public:

QueueArray(int size)
{
this->_qarray = vector< vector< type > >(size);
}

int Enqueue(const type &item, int index)
{
if( (size_t)index >= this->_qarray.size() ) {
return -1;
}

int qsize = this->Qsize(index);
this->_qarray[index].push_back(item);

if( qsize + 1 == this->Qsize(index) ) {
return 1;
}

return 0;
}

int Dequeue(type &item)
{
for( size_t i = 0; i < this->_qarray.size(); i++ ) {
if( this->_qarray[i].size() != 0 ) {
item = this->_qarray[i].front();
this->_qarray[i].erase(this->_qarray[i].begin());
return 1;
}
}

return 0;
}

int Qsize(int index) const
{
if( (size_t)index < this->_qarray.size() ) {
return this->_qarray[index].size();
}

return -1;
}

int Asize() const
{
return this->_qarray.size();
}

int QAsize() const
{
int size = 0;
for( size_t i = 0; i < this->_qarray.size(); i++ ) {
size += _qarray[i].size();
}

return size;
}

type *Qstate(int index, int &numItem) const
{
if( (size_t)index >= this->_qarray.size() ) {
return NULL;
}

type *buf = new type[this->_qarray[index].size()];
if( buf == NULL ) {
cerr << "Out of memory." << endl;
return NULL;
}

for( int i = 0; (size_t)i < this->_qarray[index].size(); i++ ) {
buf[i] = this->_qarray[index][i];
}

numItem = this->_qarray[index].size();

return buf;
}

int PrintQueue() const
{
typename vector< vector< type > >::const_iterator it1;
typename vector< type >::const_iterator it2;

for( it1 = _qarray.begin(); it1 != _qarray.end(); it1++ ) {
for( it2 = it1->begin(); it2 != it1->end(); it2++ ) {
cout << *it2 << endl;
}
cout << "--------------------" << endl;
}

return 0;
}
};

#endif




Thanks a lot, I just can't seem to make any progress on this assignment.

qofcourse
March 8th, 2006, 12:55 AM
Here are the compilation errors I'm getting in g++ (couldn't fit them in the first post):


In file included from manager.cpp:5:
queue_array.h:10: error: ISO C++ forbids declaration of `vector' with no type
queue_array.h:10: error: expected `;' before '<' token
queue_array.h: In constructor `QueueArray<type>::QueueArray(int)':
queue_array.h:16: error: `vector' undeclared (first use this function)
queue_array.h:16: error: (Each undeclared identifier is reported only once for each function it appears in.)
queue_array.h:16: error: expected primary-expression before '>' token
queue_array.h:16: error: expected primary-expression before '>' token
queue_array.h: In member function `int QueueArray<type>::QAsize() const':
queue_array.h:66: error: `_qarray' undeclared (first use this function)
queue_array.h: In member function `type* QueueArray<type>::Qstate(int, int&) const':
queue_array.h:80: error: `cerr' undeclared (first use this function)
queue_array.h:80: error: `endl' undeclared (first use this function)
queue_array.h: In member function `int QueueArray<type>::PrintQueue() const':
queue_array.h:95: error: expected nested-name-specifier before "vector"
queue_array.h:95: error: `vector' undeclared (first use this function)
queue_array.h:95: error: expected primary-expression before '>' token
queue_array.h:95: error: expected primary-expression before '>' token
queue_array.h:95: error: `::const_iterator' has not been declared
queue_array.h:95: error: expected `;' before "it1"
queue_array.h:96: error: expected nested-name-specifier before "vector"
queue_array.h:96: error: expected primary-expression before '>' token
queue_array.h:96: error: `::const_iterator' has not been declared
queue_array.h:96: error: expected `;' before "it2"
queue_array.h:98: error: `it1' undeclared (first use this function)
queue_array.h:98: error: `_qarray' undeclared (first use this function)
queue_array.h:99: error: `it2' undeclared (first use this function)
queue_array.h:100: error: `cout' undeclared (first use this function)
queue_array.h:100: error: `endl' undeclared (first use this function)
manager.cpp: At global scope:
manager.cpp:11: error: expected `,' or `...' before "readFrom"
manager.cpp:39: error: expected `,' or `...' before "cmds"
manager.cpp:43: error: expected unqualified-id before '[' token
manager.cpp: In member function `void ProgramArray::setCommands(char*)':
manager.cpp:39: error: 'class ProgramArray' has no member named 'commands'
manager.cpp:39: error: `cmds' undeclared (first use this function)
manager.cpp: In member function `int ProgramArray::getCommands()':
manager.cpp:40: error: 'class ProgramArray' has no member named 'commands'
manager.cpp: At global scope:
manager.cpp:75: error: ISO C++ forbids initialization of member `timeSlice'
manager.cpp:75: error: making `timeSlice' static
manager.cpp:75: error: ISO C++ forbids in-class initialization of non-const static member `timeSlice'
manager.cpp:78: error: new types may not be defined in a return type
manager.cpp:78: error: two or more data types in declaration of `report'
manager.cpp:78: error: two or more data types in declaration of `report'
manager.cpp: In function `ProgramArray report()':
manager.cpp:79: error: `cout' undeclared (first use this function)
manager.cpp:79: error: `endl' undeclared (first use this function)
manager.cpp: In constructor `ProgramArray::ProgramArray(char, int, int, int, int)':
manager.cpp:120: error: invalid conversion from `char' to `const char*'
manager.cpp:120: error: initializing argument 1 of `std::basic_ifstream<_CharT, _Traits>::basic_ifstream(const char*,
std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]'
manager.cpp:122: error: `commands' undeclared (first use this function)
manager.cpp:122: error: `commandCounter' undeclared (first use this function)
manager.cpp: At global scope:
manager.cpp:129: error: expected `,' or `...' before "readFrom"
manager.cpp: In constructor `ProgramArray::ProgramArray(char*)':
manager.cpp:130: error: expected primary-expression before '=' token
manager.cpp:131: error: expected primary-expression before '=' token
manager.cpp:133: error: 'class ProgramArray' has no member named 'commands'
manager.cpp:133: error: expected primary-expression before '=' token
manager.cpp:133: error: `readFrom' undeclared (first use this function)
manager.cpp:133: error: expected primary-expression before ';' token
manager.cpp:134: error: invalid conversion from `time_t (*)(time_t*) throw ()' to `int'
manager.cpp: At global scope:
manager.cpp:138: error: variable or field `block' declared void
manager.cpp:138: error: missing template arguments before '*' token
manager.cpp:138: error: `blockedState' was not declared in this scope
manager.cpp:138: error: expected primary-expression before '*' token
manager.cpp:138: error: `cpu' was not declared in this scope
manager.cpp:138: error: initializer expression list treated as compound expression
manager.cpp:138: error: expected `,' or `;' before '{' token
manager.cpp:148: error: variable or field `executeProc' declared void
manager.cpp:148: error: `queue_array' was not declared in this scope
manager.cpp:148: error: `readyState' was not declared in this scope
manager.cpp:148: error: expected primary-expression before '*' token
manager.cpp:148: error: `cpux' was not declared in this scope
manager.cpp:148: error: initializer expression list treated as compound expression
manager.cpp:148: error: expected `,' or `;' before '{' token
manager.cpp: In function `int main(int, char**)':
manager.cpp:180: error: no matching function for call to `ProgramArray::ProgramArray()'
manager.cpp:8: note: candidates are: ProgramArray::ProgramArray(const ProgramArray&)
manager.cpp:129: note: ProgramArray::ProgramArray(char*)
manager.cpp:112: note: ProgramArray::ProgramArray(char, int, int, int, int)
manager.cpp:181: error: `queue_array' undeclared (first use this function)
manager.cpp:181: error: `readyState' undeclared (first use this function)
manager.cpp:182: error: missing template arguments before '*' token
manager.cpp:182: error: `blockedState' undeclared (first use this function)
manager.cpp:186: error: `newProcess' undeclared (first use this function)
manager.cpp:189: error: `read_fd' undeclared (first use this function)
manager.cpp:194: error: `currentlyExecuting' undeclared (first use this function)
manager.cpp:198: error: invalid types `<unknown type>[int]' for array subscript
manager.cpp:200: error: `i' undeclared (first use this function)
manager.cpp:200: error: insufficient contextual information to determine type
manager.cpp:206: error: insufficient contextual information to determine type
manager.cpp:212: error: insufficient contextual information to determine type
manager.cpp:221: error: `block' cannot be used as a function
manager.cpp:222: error: `executeProc' cannot be used as a function
manager.cpp:225: error: `null' undeclared (first use this function)
manager.cpp:226: error: wrong type argument to bit-complement
manager.cpp:227: error: `executeProc' cannot be used as a function
manager.cpp:103: error: too few arguments to function `ProgramArray* duplicateProcess(CPU*, int, int)'
manager.cpp:230: error: at this point in file
manager.cpp:231: error: expected primary-expression before ';' token
manager.cpp:232: error: `readyQueue' undeclared (first use this function)
manager.cpp:235: error: insufficient contextual information to determine type
manager.cpp:238: error: cannot convert `std::string' to `const char*' for argument `1' to `int atoi(const char*)'
manager.cpp:244: error: invalid types `<unknown type>[int]' for array subscript
manager.cpp:245: error: expected primary-expression before "char"
manager.cpp:245: error: expected `;' before "char"
manager.cpp:251: error: invalid conversion from `char' to `const char*'
manager.cpp:251: error: initializing argument 1 of `std::basic_ifstream<_CharT, _Traits>::basic_ifstream(const char*,
std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]'
manager.cpp:253: error: `newCmds' undeclared (first use this function)
manager.cpp:268: error: invalid use of member (did you forget the `&' ?)
manager.cpp:268: error: base operand of `->' is not a pointer
manager.cpp:269: error: `blockedQueue' undeclared (first use this function)
manager.cpp:269: error: `block' cannot be used as a function
manager.cpp:270: error: `executeProc' cannot be used as a function

laserlight
March 8th, 2006, 01:08 AM
Many of your errors are due to the use of names in the std namespace without fully qualifying them with std::, e.g. vector should be std::vector, and cerr should be std::cerr.

qofcourse
March 8th, 2006, 01:26 AM
You're right, I didn't even notice that queue_array.h wasn't using namespace std. Thanks, that cleared up all the queue_array related errors :)

JohnyDog
March 8th, 2006, 04:42 AM
Although it works, you shouldn't use 'using namespace' in header files, as it propagates into all files including it and unnecessary pollutes global namespace. Try to use full namespace qualifiers, or 'using' only (e.g. 'using std::vector').

Anyway, your code is full of syntactical errors, did you try compiling it when you were writing it? You should read more about C/C++ syntax (and pointers). For example to define array of chars, you have to write 'char xx[50]' instead of 'char[50] xx'. Also you cannot use char[] in parameter list, if you want to pass array of unknown size, you have to pass pointer to it like:


int function(char *a)
{
}
...
char xx[50];
function(&xx);


Also you should use std::string instead of char arrays where it is possible.

SuperKoko
March 8th, 2006, 04:56 AM
JohnyDog : I would like to correct two mistakes in your post:

Also you cannot use char[] in parameter list, if you want to pass array of unknown size, you have to pass pointer to it like:

It is legal to use a array-declaration-like syntax in a parameter list, though it is perfectly equivalent to a pointer, and more confusing for learners.

void Function(char p[42]);
/* it is equivalent to */
void Function(char p[]);
/* or to */
void Function(char *p);


Second correction, your code has an incorrect type coercion:

int function(char *a)
{
}
...
char xx[50];
function(xx); /* you must not take the address of the array, which yeilds to a char(*)[50], while we want a char* */

JohnyDog
March 8th, 2006, 05:05 AM
SuperKoko: Ah, sorry, i wanted to say exactly that, just got lost in the process :)

NMTop40
March 8th, 2006, 07:49 AM
What is the significance here of each vector in queue_array ?

You don't need to use this-> to refer to a class member (in fact I find it a waste of space and slightly confusing).

new doesn't return NULL if it fails, unless you use new(nothrow) which you shouldn't.

You have a function call Qstate which returns a newly created pointer. It's not obvious that a name such as Qstate should return such a thing. (The function doesn't have a name that indicates it creates something. If you did have to do this use the word "create" in the function).

Can't it just return vector<type> ? But in fact it seems to just be returning a clone of _qarray[index] so why not return const vector<type> & and return _qarray[index] directly?

If you really have to return a pointer you can return const type * and return &_qarray[index][0] although you'd have to check if _qarray[index] is empty.

qofcourse
March 8th, 2006, 04:22 PM
Thanks for the suggestions thus far, I went through and cleaned up most of the syntax errors. I use this-> to refer to class members just for clarity, I find it actually eliminates some confusion in my mind. The queue_array.h file was written by the class TA, and I'm not really supposed to change it.

What I havent been able to fix yet are the "block cannot be used as a function" (and related) errors. I don't see any reason it can't be used as a function, because it is a function (I declared it at the top of the file for the sake of testing, and had the same problem).

Why might it be telling me this? Unless I'm missing something, I don't see anything else in manager.cpp that I can change to make block usable as a function.

JohnyDog
March 9th, 2006, 08:47 AM
What I havent been able to fix yet are the "block cannot be used as a function" (and related) errors. I don't see any reason it can't be used as a function, because it is a function (I declared it at the top of the file for the sake of testing, and had the same problem).

Can you post the code with fixed bugs? The error in question is probably just a symptom of other errors which causes the function to be unusable by compiler.