I am trying to change the array in this program from a static array into a dynamic array. I'm totally lost on this one and could use a little help. There are a few other problems in the program, but the only thing I'm worried about right now is getting this from a static array to a dynamic array.

The program is supposed to take a given list of values and insert it into an array, delete any duplicates, and sort in ascending order. It will then read another list of values with an "a" or "d" in front of each value and add t he value if there is an "a" or delete the value if there is a "d." Finally the program outputs the updated list of values into a new file.

All I need to do here is switch the arrays from being statically defined to being dynamically defined. Probably not really that hard to do, but I'm new to this. I tried a few different things, but I keep getting memory leaks. Any help would be appreciated.

#include<iostream>
#include<fstream>
using namespace std;
#define MAX_SIZE 2000

int search(int value, int list[], int n);
void storeValue(int value, int list[], int& n);
void deleteValue(int value, int list[], int &n);

int main()
{
   int list[MAX_SIZE];                     
   int n = 0;                              
   int value;                              
   fstream inFile("invent.dat", ios::in);  
   while(inFile >> value)
   {
      if(search(value, list, n) == -1)
         storeValue(value, list, n);
   }
   inFile.close();                     
   cout << "Database has " << n << " ID numbers \n------------------------------------------\n";
   char action;                        
   fstream upFile("update.dat", ios::in); 
   while(upFile >> action >> value)
   {
      if(action == 'a' || action == 'A')
      {
         if(search(value, list, n) == -1);
            storeValue(value, list, n);
      }
      if((action == 'D' || action == 'd') && search(value, list, n) != -1)
      {
         deleteValue(value, list, n);
      }
   }
   upFile.close();                         
   fstream outFile("final.dat", ios::out); 
   for(int i = 0; i < n; i++)
      outFile << list[i] << '\n';
   cout << "Updated Database \nDatabase has " << n << " ID numbers \n\n";
   return 0;
}

int search(int value, int list[], int n)
{
   for(int i = 0; i < n; i++)
   {
      if(list[i] == value)
         return 0;
   }
   return -1;
}

void storeValue(int value, int list[], int& n)
{
   int loc = 0;       
   for(loc = 0; loc < n; loc++)
   {
      if(value < list[loc])
         break;
   }
   for(int i = n; i > loc; i--)
   {
      list[i] = list[i-1];
   }
   list[loc] = value;
   n++;
}

void deleteValue(int value, int list[], int& n)
{
   int loc;
   for(int i = 0; i < n; i++)
   {
      if(list[i] == value)
         loc = i;
   }
   
   for(int i = loc; i < n - 1; i++)
   {
      list[i] = list[i+1];
   }
   n--;
}
Salem commented: Excellent first post - indented code posted with code tags - thanks +19

Recommended Answers

All 10 Replies

pass pointers to functions instead of arrays. In the main dynamically allocate memory using new keyword on the first line. Believe that should work.

int search(int value, int* list, int n);
void storeValue(int value, int* list, int& n);
void deleteValue(int value, int* list, int &n);

int main()
{
   int n = 0;   
   int* list = new(nothrow) int[n];                                     
   int value;                              
   fstream inFile("invent.dat", ios::in);  
   while(inFile >> value)
   {
      if(search(value, list, n) == -1)
         storeValue(value, list, n);
   }
   inFile.close();                     
   cout << "Database has " << n << " ID numbers \n------------------------------------------\n";
   char action;                        
   fstream upFile("update.dat", ios::in); 
   while(upFile >> action >> value)
   {
      if(action == 'a' || action == 'A')
      {
         if(search(value, list, n) == -1);
            storeValue(value, list, n);
      }
      if((action == 'D' || action == 'd') && search(value, list, n) != -1)
      {
         deleteValue(value, list, n);
      }
   }
   upFile.close();                         
   fstream outFile("final.dat", ios::out); 
   for(int i = 0; i < n; i++)
      outFile << list[i] << '\n';
   cout << "Updated Database \nDatabase has " << n << " ID numbers \n\n";
   return 0;
}

int search(int value, int* list, int n)
{
   for(int i = 0; i < n; i++)
   {
      if(list[i] == value)
         return 0;
   }
   return -1;
}

void storeValue(int value, int* list, int& n)
{
   int loc = 0;       
   for(loc = 0; loc < n; loc++)
   {
      if(value < list[loc])
         break;
   }
   for(int i = n; i > loc; i--)
   {
      list[i] = list[i-1];
   }
   list[loc] = value;
   n++;
}

void deleteValue(int value, int* list, int& n)
{
   int loc;
   for(int i = 0; i < n; i++)
   {
      if(list[i] == value)
         loc = i;
   }
   
   for(int i = loc; i < n - 1; i++)
   {
      list[i] = list[i+1];
   }
   n--;
}

Anything like that? I understand most C++ stuff, but for some reason this just isn't sticking. Do I have to do a lot of other work inside the functions as well, or just change the definitions?

basically imagine a box and point your finger to it. That's basically a pointer. That's what you are doing on the first line.

don't need code shown on bottom. other than that it looks good.

(nothrow)

I'm getting this error message when I try to run after compilation. Any idea what it could mean?

Reading invent.dat 
terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_filebuf::underflow error reading the file
Segmentation fault

pass pointers to functions instead of arrays.

Passing int list[] is the same thing as passing int *list. The array "degrades" to a pointer when it's passed in.

So if passing int list[] is the same as passing int *list, is there something else I need to do to make this work?

So I'm still working on it, but I think I must be declaring the array wrong at the beginning. When I try to run it I get this massive error message that I think must be a memory leak. It has these lines with a bunch of memory locations between them and after the memory map. The error ends with an Aborted message.

#
======= Backtrace: =========
.
.
.
.
======= Memory map: ========
.
.
.
.

If you still have the following code ..

int n = 0;   
int* list = new(nothrow) int[n];

then you are thrashing memory (you'll get a pointer to a zero-sized memory block). So you need to re-think how to allocate the memory. Also make sure that the allocation succeeds i.e. check that new [] did not return NULL.

[EDIT]
Remember to

delete [] list;

too.

like that. don't forget to delete after your done using as mentioned above.

int n = 2;   
int* list = new int[n];

In trying to help this OP I've tried to implement it using:

void storeValue(int value,int *&list,int & n)
{
	int * temp = new int[n+1];
  ... //if this is correct I don't want to steal all the fun
  ... //with the stuff in here but I can post if nec.
      
        //delete list
       //assigning temp back to list
        //delete temp
}

(and I tried it with ** too -- which is what I think lotrsimp was getting at so apologies) but despite all of the careful passing the array it is gone once it gets back to main. I know I'm making some sort of fundamental error here but I cannot figure it out for the life of me. To the OP thanks for letting me side track things a bit but I think this will point you towards a solution.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.