-2

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;
        ^
`
6
  • I have debugged, I have provided the example, I have located the exact spot of the error, and now I'm wondering if someone could give it a glance and see if it's simply implemented wrong. Anyone that knows c++ well would recognize the problem wrong if I fluffed on the specific line of code I pointed out. You posted this comment less than 10 seconds after I made this post. Just downvoted and flamed without giving it a glace -_- I feel like I've done enough work on my own to merit asking for a quick glance from a nice soul with a minute to spare. Commented May 20, 2017 at 19:55
  • Shouldn't it be asterisk p and not p asterisk? Commented May 20, 2017 at 20:12
  • 1
    @JeffreyDilley "You posted this comment less than 10 seconds after I made this post" Sure, that is a stock comment I use frequently. At the 1st glance it wasn't clear that you are suffering from basic compiler errors and not lack of debugging efforts as it's usual with that knid of VLQ questions. You should learn how to interpret compiler errors correctly. There's not much value about asking such stuff here. Commented May 20, 2017 at 20:14
  • @JeffreyDilley Please adopt uniform formatting. Sometimes you put in no spaces, sometimes you do, even twice. Same thing with newlines. Indentation is weird as it is. Writing your code like you care makes a better programmer. Unless you want to make OCD people suffer. Commented May 20, 2017 at 20:21
  • I stopped looking at code right here... p* = cacheArr[alphaNum]; Or was your intention to try to dereference the assignment operator? Commented May 20, 2017 at 20:57

1 Answer 1

1

There are at least two problems.

p* = cacheArr[alphaNum]; should be *p = cacheArr[alphaNum];

Then, in that same function, p-> should be (*p)->, since p is a pointer to a pointer.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.