I'm working on a rather long-winded assignment that currently has one fatal problem. I'm unable to correctly implement a nodes access to the data stored in a linked list stored in a pointer.
At first I was getting a segmentation error, but after some research like this and this I was able to clear that up. Now that I've fixed the segmentation error, my code won't even compile!
I've "cout" debugged to the point I know that the problem exists in my Cache.h file, specifically in my addElement function when I try to set a new node p equal to the starting node of some array value. Tried to clearly comment.
because my array is an array of linked lists, it's essentially an array of pointers. Type is declared as node *. I feel like p should then be a pointer to a pointer, since it's not a part of any list and needs to access data through the array. I've tried about a million combinations of pointers and pointers to pointers, however nothing allowed me to even compile again. I've done just about all the debugging I know how to do, so I turn to you.
I'm going to post the code below. commands.in essentially houses name of the files I'll be using. A.data is the file whose data I'm doing an operation on it's (minfor ex). Process.cpp houses my main function, as well as basic operations and Cache.h really just exists to have this pointer.
Since the problem certainly exists in Cache.h I'll be posting that first, everything else to follow. Again, error location should be obvious. Hoping it's some mistake with my understanding of pointers and an easy fix.
Thanks!
Cache.h`
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
//CLASS TO STORE SIMPLE "CACHE"
class Cache
{
private:
struct node
{
double val;
string cacheName;
string cacheOp;
node * next;
};
node * cacheArr[26];
public:
//CONSTRUCTOR, SET VALUES OF cacheArr TO NULL
Cache()
{
for (int i = 0; i < 26; i++)
{
cacheArr[i] = new node;
}
}
//ADD AN ELEMENT TO CACHE
void addElement (string file, string op, double value)
{
node** p;
char ch = file[0];
//convert
int alphaNum = (int)(ch - 'A');
cout << "\nALPHA NUM = " << alphaNum << " -- ch = " << ch << endl;
cout << "TEST PRE";
/*
HERE LIES THE PROBLEM
vvvvvvvvvvvvvvvvvvvvv
*/
p* = cacheArr[alphaNum];
cout << "\nTEST";
if (p == NULL)
{
//no values starting with 'ch' have been used
//create new node
p->cacheName = file;
p->cacheOp = op;
p->val = value;
p->next = NULL;
return;
}
else if (p->next == NULL)
{
//list has one value, add to list if so
p = p->next;
p->cacheName = file;
p->cacheOp = op;
p->val = value;
p->next = NULL;
return;
}
//list has 2+ elements
//bring p to last element
while(p!=NULL)
{
p = p->next;
}
` //p is at end of list
p->cacheName = file;
p->cacheOp = op;
p->val = value;
p->next = NULL;
return;
}
//checks to see if file already in cache
bool checkCache(string file, string op)
{
char ch = file[0];
int numAlpha = (int)(ch - 'A' + 1);
node* p = cacheArr[numAlpha];
if(p == NULL)
{
return false;
}
while(p!=NULL)
{
if(p->cacheName == file && p->cacheOp == op)
{
return true;
}
p = p->next;
}
return false;
}
//RETURNS VALUE OF CACHE
double getVal(string file, string op)
{
char ch = file[0];
int numAlpha = (int)(ch - 'A' + 1);
node * p = cacheArr[numAlpha];
while (p!=NULL)
{
if(p->cacheName == file && p->cacheOp == op)
{
return p->val;
}
p = p->next;
}
return 0;
}
};
//END OF CLASS
Process.cpp:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <ctime>
#include "Cache.h"
using namespace std;
//PROTOTYPE
double Avg(string fileName);
int Min(string fileName);
int Max(string filename);
double Med(string filename);
int main(){
//VARIABLES
int numFile;
string fileName;
string opName;
fstream fileObj;
double result;
ofstream resultFile;
Cache cacheObj;
bool inCache;
double elapsed_secs;
//OPEN FILES. READ FROM fileObj, WRITE TO resultFile
resultFile.open("results.out");
cout << "\n\n\n\n\n\n" << endl;
fileObj.open("commands.in");
fileObj >> numFile;
//ITERATE THROUGH FILES IN commands.in
for (int i = 0; i < numFile; i++){
fileObj >> fileName;
fileObj >> opName;
//CHECK IF IN CACHE
inCache = cacheObj.checkCache(fileName, opName);
if (inCache==false)
{
//DO AVG OP
if (opName == "Avg")
{
cout << "\n\nAvg file found. Filename = " << fileName<<endl;
clock_t begin = clock();
result = Avg(fileName);
cout << "test";
clock_t end = clock();
cacheObj.addElement(fileName, opName, result);
elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
cout << "Time for OP : " << elapsed_secs << endl;
cout << "result = " << result;
resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds" << endl;
}
//DO MIN OP
if (opName == "Min")
{
cout <<"\n\nMin file found. Filename = " << fileName << endl;
clock_t begin = clock();
result = Min(fileName);
clock_t end = clock();
cacheObj.addElement(fileName, opName, result);
elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
cout << "Time for OP : " << elapsed_secs << endl;
cout << "result = " << result;
resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds" << endl;
}
//DO MAX OP
if (opName == "Max")
{
cout <<"\n\nMax file found. Filename = " << fileName << endl;
clock_t begin = clock();
result = Max(fileName);
clock_t end = clock();
cacheObj.addElement(fileName, opName, result);
elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
cout << "Time for OP : " << elapsed_secs << endl;
cout << "result = " << result;
resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds" << endl;
}
//DO MED OP
if (opName == "Med")
{
cout << "\n\nMed file found. Filename = " << fileName << endl;
clock_t begin = clock();
result = Med(fileName);
clock_t end = clock();
cacheObj.addElement(fileName, opName, result);
elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
cout << "Time for OP : " << elapsed_secs << endl;
cout << "result = " << result;
resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds" << endl;
}
}else if(inCache == true)
{
clock_t begin = clock();
result = cacheObj.getVal(fileName, opName);
clock_t end = clock();
elapsed_secs = double(end-begin) / CLOCKS_PER_SEC;
cout << "Time for OP: " << elapsed_secs << endl;
resultFile << fileName << " " << opName << ": " << result << " in " << elapsed_secs << " seconds " << endl;
}
//END OF FOR LOOP
}
//END OF MAIN
return 0;
}
//COMPUTE AVG AS DOUBLE, RETURN
double Avg(string filename)
{
fstream file;
string name = filename + ".data";
file.open(name.c_str());
if (file.fail())
{
cout << "The file was not found" << endl;
return 0;
}
int count = 0;
double allNum = 0;
double current;
double result;
while(file)
{
file >> current;
allNum += current;
count++;
}
//WHY IS IT ADDING THE FINAL NUMBER TWICE?!
//THIS PART OF THE CODE IS BROKEN
result = allNum / count-1;
return result;
}
//COMPUTE THE MIN AS INT
int Min(string filename)
{
fstream file;
string name = filename + ".data";
file.open(name.c_str());
if (file.fail())
{
cout << "The file was not found" << endl;
return 0;
}
int min;
int test;
file >> min;
while (file)
{
file >> test;
if (test < min)
min = test;
}
return min;
}
//COMPUTE MAX AS INT
int Max(string filename)
{
fstream file;
string name = filename + ".data";
file.open(name.c_str());
if (file.fail())
{
cout << "The file was not found" << endl;
return 0;
}
int max = 0;
int test;
file >> max;
while (file)
{
file >> test;
if (test > max)
max = test;
}
return max;
}
//COMPUTE THE MED
double Med(string filename){
fstream file;
string name = filename + ".data";
file.open(name.c_str());
if (file.fail())
{
cout << "The file was not found" << endl;
return 0;
}
double val;
vector<double> medVect;
int count = 0;
//store file in vector
while(file)
{
file >> val;
medVect.push_back(val);
count++;
}
//sort the vector
double temp;
int vSize = medVect.size();
for (int i = 0; i < vSize; i++)
{
for (int j = 0; j < vSize; j++)
{
if (medVect.at(i) > medVect.at(j))
{
temp = medVect.at(i);
medVect.at(i) = medVect.at(j);
medVect.at(j) = temp;
}
}
}
//find the median for:
//odd values
if (vSize %2 == 1)
{
int mid = vSize / 2;
return medVect.at(mid+1);
}
int mid = vSize / 2;
double mid1 = medVect.at(mid);
double mid2 = medVect.at(mid+1);
double result = (mid1 + mid2) / 2;
return result;
//SAME THING, CODE READS LAST LINE OF FILE TWICE...NEED TO FIX
}
Commands.in
6
A Min
B Max
C Avg
A2 Max
B Max
ABC Med
A.Data`
20
20
30
30
40
40
`
Forgot, The error codes I'm getting.`
[dilleyj@cs1 HW6]$ g++ -Wall -o process Process.cpp
In file included from Process.cpp:6:0:
Cache.h: In member function ‘void Cache::addElement(std::string, std::string, double)’:
Cache.h:59:7: error: expected primary-expression before ‘=’ token
p* = cacheArr[alphaNum];
^
Cache.h:67:8: error: request for member ‘cacheName’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->cacheName = file;
^
Cache.h:68:8: error: request for member ‘cacheOp’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->cacheOp = op;
^
Cache.h:69:8: error: request for member ‘val’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->val = value;
^
Cache.h:70:8: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->next = NULL;
^
Cache.h:73:16: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
else if (p->next == NULL)
^
Cache.h:76:14: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p = p->next;
^
Cache.h:77:9: error: request for member ‘cacheName’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->cacheName = file;
^
Cache.h:78:9: error: request for member ‘cacheOp’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->cacheOp = op;
^
Cache.h:79:9: error: request for member ‘val’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->val = value;
^
Cache.h:80:9: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->next = NULL;
^
Cache.h:88:13: error: request for member ‘next’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p = p->next;
^
Cache.h:93:8: error: request for member ‘cacheName’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->cacheName = file;
^
Cache.h:94:8: error: request for member ‘cacheOp’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->cacheOp = op;
^
Cache.h:95:8: error: request for member ‘val’ in ‘* p’, which is of pointer type ‘Cache::node*’ (maybe you meant to use ‘->’ ?)
p->val = value;
^
`