Reputation: 11
I am trying to make a dynamic array in my member function, however, it seems to create a new dynamic array each time I call the function. Is there anyway to create a dynamic array inside a member function so it doesn't remake itself.
class predator
{
private:
string name;
string species;
protected:
string *list;
public:
predator(string theSpecies);
void killsRecorded(string kills); // add a new kill to the end of the predator's list of kills
string *killsList(); // return a pointer to the array of all kills by this predator
int noOfTotalKills(); // how many kills have been recorded
int k;
static int n;
};
//The header file
void predator::killsRecorded(string kills)
{
k = 0;
list = new string[5];
*(list + k) = kills;
k = n++;
cout<< k<< endl;
}
string* predator::killsList()
{
//cout<< (sizeof(list)/sizeof(list[0]))<< endl;
for(int i=0; i<5; i++)
{
cout<< *(list + i)<< endl;
}
}
Above is my class and header file, void killsRecorded(string kills) should add kills to my array, however, when I try that in my main.
predator *prey;
prey = new predator("Cheetah");
prey->killsRecorded("Mouse");
prey->KillsRecorded("Donkey");
prey->killsList();
It prints out
Created a hunter that is a Cheetah
0
1
Donkey
*BLANK LINE
*BLANK LINE
*BLANK LINE
*BLANK LINE
Instead, Mouse should be in the first line and Donkey in the second. Am I doing something wrong? Also, I can't use vectors, it's for an assignment.
Upvotes: 0
Views: 915
Reputation: 2259
You should use std::vector... to do that you have to
#include <vector>
with the command
std::vector<string> kills;
you can create a new vector of strings
with the command
kills.pushback(stringvalue);
you can add a new string into your vector "list" also you don't have to count your kills... you can use
kills.size();
to get the number of strings back. To get the values (strings) back you can use the vector like an array
string name = kills[3];
btw: you should save the vector as a member... to do that you have to save it in your class definition (header)
If you arn't allowed to use std::vector, you can write your own list...
class list
{
private:
node* head;
int size = 0;
struct node
{
node* next;
string value;
}
public:
list();
~list();
void PushBack(string);
string GetElement(int index);
int GetSize();
};
list::list()
{
head = new list();
head->next = nullptr;
}
list::~list()
{
node* temp = head;
node* temp2 = temp;
do //delete hole list
{
temp2 = temp->next;
delete temp;
temp = temp2;
}while(temp != nullptr);
}
void list::PushBack(string item)
{
node* temp = head;
while(temp->next != nullptr)
{
temp = temp->next;
}
//found the end of the list
node* newNode = new node();
newNode->value = item;
newNode->next = nullptr;
temp->next = newNode;
size++;
}
int list::GetSize()
{
return size;
}
string list::GetElement(int index)
{
node* temp = head;
while(temp->next != nullptr)
{
temp = temp->next;
if(index == 0)
{
return temp->value;
}
index--;
}
//index out of bounds
return "";
}
I can not check if the code is correct at the moment, because on this computer is no IDE... but I think it should word ;)
BTW: you can use this list instead of an array to do that you have to write:
list kills;
kills.PushBack("Peter");
kills.PushBack("Thomas");
kills.PushBack("Alex");
for(int i = 0; i< kills.GetSize();i++)
{
std::cout<<kills.GetElement(i)<<std::endl;
}
Upvotes: 0
Reputation: 148910
Hmm, your killsRecorded(string kills)
method is an example of how not to program...
new[]
which leads to a memory leak (how could you free them now your program has forgotten what had been allocated)What should be done (what vector class does under the hood):
Code could be:
class predator
{
private:
string name;
string species;
protected:
string *list;
size_t max_size;
size_t cur_size;
public:
predator(string theSpecies);
void killsRecorded(string kills); // add a new kill to the end of the predator's list of kills
string *killsList(); // return a pointer to the array of all kills by this predator
int noOfTotalKills(); // how many kills have been recorded
/*int k; what it that???
static int n;*/
};
//The implementation file
predator(string theSpecies): species(species) {
list = new string[5];
max_size = 5;
cur_size = 0;
// what do you do with name ?
}
void predator::killsRecorded(string kills)
{
if (cur_size >= max_size) { /* need a bigger array */
max_size *= 2;
temp = new string[max_size];
for(int i=0; i<cursize; i++) { // copy previous recorded values
temp[i] = list[i];
}
delete[] list; // free previous allocated array
list = temp; // ok list is now big enough
}
list[cur_size++] = kills;
}
Upvotes: 0
Reputation: 141
In your constructor, assign n a default value, say 5. Then create an array of that size.
predator::predator()
: n(5),
k(0)
{
kills = new string[n];
}
Then recordKills checks to see if there is space in kills, reallocating if necessary:
recordKills(string kill)
{
if(k >= n) {
string* oldKills = kills;
kills = new string[2*n];
// copy
for(int i = 0; i< n: i++) {
kills[i] = oldKills[i];
}
n *= 2;
delete [] oldKills;
}
kills[k++] = kill;
}
It's generally a bad idea to call a variable by the name of a data structure, so I renamed 'list' to 'kills'.
Then when printing the kills, loop until k:
string* listKills()
{
for(int i = 0; i < k; i++) {
cout << kills[i] << endl;
}
return kills;
}
Remember to delete kills in the destructor!
Upvotes: 1