Jump to content

Statically allocated arrays to Dynamically C++

ExplOregon

Hello Friends, 

 

I was wondering if anyone could give some pointers on how I would change

my current program from the arrays being statically allocated to dynamically

allocated.  I also need to create an array of animals that I have from a struct

to be dynamic as well. I appreciate any pointers on where to change my code

 

Thanks

.H File

.CPP File

Link to comment
Share on other sites

Link to post
Share on other sites

just to clarify, do you want the array to have a dynamic size? or do you want a dynamic number of arrays. or have i missed it completely?

so do you want something like a vector?

Link to comment
Share on other sites

Link to post
Share on other sites

Use a std::vector, it is quick, works perfectly and is easy to use. If not, you need to use dynamic memory allocation such as:

int* pArray = new int[iCount];

Remember to delete the free the allocated memory after:

delete[] pArray;

 

Link to comment
Share on other sites

Link to post
Share on other sites

On 2/21/2016 at 0:25 AM, uzarnom said:

just to clarify, do you want the array to have a dynamic size? or do you want a dynamic number of arrays. or have i missed it completely?

so do you want something like a vector?

Basically I want to have an Animal_Shelter class that contains a dynamically allocated array of animals that are in its care.

 

On 2/24/2016 at 8:17 PM, PantherNZ said:

Use a std::vector, it is quick, works perfectly and is easy to use. If not, you need to use dynamic memory allocation such as:


int* pArray = new int[iCount];

Remember to delete the free the allocated memory after:


delete[] pArray;

 

I think my professor doesn't wants us to use vectors, you can see on line 7 how it assumes that it statically allocated 100 animals, how would I change that to be dynamic?

Link to comment
Share on other sites

Link to post
Share on other sites

So the main thing when creating a dynamic array is that you need to allocate it to the heap rather than the stack (not 100% correct but to keep it simple lets say that is the case). This means you want to use the new operator which means you will get the address of the newly allocated memory returned which would look something like this 

 

animal* inventory = new animal[100];

So now this memory is dynamically allocated, you can change the number 100 to be a variable that you assign run time rather than having to have it defined compile time.

To access the memory you do the same as before and just use the subscript operator (obj[index]).

 

My assumption is that your professor wants you to increase the size of the array once you hit the max, in which case you will want to create a new array, copy the current data over to the new memory and then delete the old array which could look something like this

 

int sizeOfInventory = 1;
animal* inventory = new animal[sizeOfInventory];
animal[0].name = "bob";

animal* newInv = new animal[sizeOfInventory * 2];
memcpy(newInv, inventory, sizeof(animal) * sizeOfInventory);
sizeOfInventory = sizeOfInventory * 2;
delete[] inventory;
inventory = newInv;

 

So step by step what happens here

  1. Create int to store the current size of the array
  2. Dynamically allocate array to heap and assign to pointer
  3. Set animal name to bob
  4. Dynamically allocate a new array to heap and assign to pointer
  5. Copy the original array to the new array (new array location, old array location, byte count to copy)
  6. Set the current size of the array to the new array's size
  7. Deallocate original array from heap
  8. Assign inventory pointer to the new array's address

PantherNZ already covered the basics of this above but it seems you were still a little confused so hope this helps you understand the process

Link to comment
Share on other sites

Link to post
Share on other sites

21 hours ago, MSVSora said:

So the main thing when creating a dynamic array is that you need to allocate it to the heap rather than the stack (not 100% correct but to keep it simple lets say that is the case). This means you want to use the new operator which means you will get the address of the newly allocated memory returned which would look something like this 

 


animal* inventory = new animal[100];

So now this memory is dynamically allocated, you can change the number 100 to be a variable that you assign run time rather than having to have it defined compile time.

To access the memory you do the same as before and just use the subscript operator (obj[index]).

 

My assumption is that your professor wants you to increase the size of the array once you hit the max, in which case you will want to create a new array, copy the current data over to the new memory and then delete the old array which could look something like this

 


int sizeOfInventory = 1;
animal* inventory = new animal[sizeOfInventory];
animal[0].name = "bob";

animal* newInv = new animal[sizeOfInventory * 2];
memcpy(newInv, inventory, sizeof(animal) * sizeOfInventory);
sizeOfInventory = sizeOfInventory * 2;
delete[] inventory;
inventory = newInv;

 

So step by step what happens here

  1. Create int to store the current size of the array
  2. Dynamically allocate array to heap and assign to pointer
  3. Set animal name to bob
  4. Dynamically allocate a new array to heap and assign to pointer
  5. Copy the original array to the new array (new array location, old array location, byte count to copy)
  6. Set the current size of the array to the new array's size
  7. Deallocate original array from heap
  8. Assign inventory pointer to the new array's address

PantherNZ already covered the basics of this above but it seems you were still a little confused so hope this helps you understand the process

This helped a lot, but since she wants it to only grow once something is added what would change?

Link to comment
Share on other sites

Link to post
Share on other sites

32 minutes ago, ExplOregon said:

This helped a lot, but since she wants it to only grow once something is added what would change?

Well, you have a function which is called "addAnimal", in this function you would want to basically, check the current animal count (which you need to store in the class as a member variable and default it to 0 along with having another member variable for the current max size of the array. If the current animal count is the same as the max size of the array, you want to then call a new function which will resize your array to a size you specify, which would be the code previously given.

 

void animal_shelter::growArray(unsigned int aNewArraySize)
{
	assert(aNewArraySize > 0 && "Invalid array size in animal_shelter::growArray");
	animal* newArry = new animal[aNewArraySize];
	memcpy(newArry, myAnimalList, sizeof(animal) * myCurrentAnimalListSize);
	myAnimalListMaxSize = aNewArraySize;
	delete[] myAnimalList;
	myAnimalList = newArry;
}

So basically the new function would look something like this

  1. Function definition
  2. Safety check to make sure we don't try to create an array with 0 size (It will crash the program if the value is equal to 0 http://www.cplusplus.com/reference/cassert/assert/ requires the assert.h header)
  3. Create a new animal array of specified size
  4. Copy the old list of animals to the new array, this will make sure that we only move animal elements we have filled by moving the active size of the array rather than the whole array
  5. Set the current max size of the array to the new max array size
  6. Delete the old array
  7. Assign member variable myAnimalList to the new array

A couple of notes here, first I have added the prefix of "my" to all member variables and the prefix of "a" to the argument, this is just part of the code standard I use to help make the code more legible.

Secondly the assert is by no means needed and is just something I added as its something I always do, really though if you are going to add asserts you should also run assert on the case that the new array size is smaller than the current number of animals in your array as this would cause an error when copying the memory but that may be a bit advanced for what your teacher expects.

 

Feel free to ask if you have any further issues :)

Link to comment
Share on other sites

Link to post
Share on other sites

On 2/27/2016 at 5:40 PM, MSVSora said:

int sizeOfInventory = 1; animal* inventory = new animal[sizeOfInventory]; animal[0].name = "bob"; animal* newInv = new animal[sizeOfInventory * 2]; memcpy(newInv, inventory, sizeof(animal) * sizeOfInventory); sizeOfInventory = sizeOfInventory * 2; delete[] inventory; inventory = newInv;

So when you said this in your initial comment, would it go inside the addAnimal function I have at the bottom?

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, ExplOregon said:

So when you said this in your initial comment, would it go inside the addAnimal function I have at the bottom?

It would go in the top of the function as you want to increase the size of the array before adding, otherwise you will be trying to add to a full array

Link to comment
Share on other sites

Link to post
Share on other sites

23 minutes ago, MSVSora said:

It would go in the top of the function as you want to increase the size of the array before adding, otherwise you will be trying to add to a full array

HALLELUJAH IT WORKS. Granted I made it all one .cpp file and my prof wants it in a class with two .cpps and a .h, now to get that figured out. Thanks for the help!

 

Link to comment
Share on other sites

Link to post
Share on other sites

22 minutes ago, ExplOregon said:

HALLELUJAH IT WORKS. Granted I made it all one .cpp file and my prof wants it in a class with two .cpps and a .h, now to get that figured out. Thanks for the help!

 

Glad its working for ya :) good luck with the rest of the assignment ^^

Link to comment
Share on other sites

Link to post
Share on other sites

On 2/28/2016 at 9:36 PM, MSVSora said:

Glad its working for ya :) good luck with the rest of the assignment ^^

Could you possibly tell me what I should put in main to make this all work?

http://imgur.com/oo5DRdG

Link to comment
Share on other sites

Link to post
Share on other sites

Sure, though first I should point out that your code wont work anyway for a couple of reasons. Maybe you are just testing atm but your addAnimal function in its current state will do nothing, except allocate new memory then delete the old.

 

Anyway to the main function it should look something like

 

int main()
{
	animalShelter shelter; //create new animalShelter
	
	//As your addAnimal function requires an animal we must first create one
	animalShelter::animal bob; //As you have your animal struct inside of animalShelter then we have to use the animalShelter scope, I would recommend moving the animal decleration to outside of the animalShelter class. 
	bob.name = "Bob";
	bob.age = 10;
	bob.breed = "Robot";
	bob.weight = 2000;
	bob.friendly = "No clue"; //Not sure what this is supposed to be but seems like something that should be a bool?
	bob.description = "Some random text here about Bob";

	shelter.addAnimal(bob); //This is rather weird to do considering you also require the input inside the addAnimal function
	shelter.displayAll(); //This will currently not display anything as you currently don't actually store the animal

	return 0;
}

 

Also I would recommend you post your testing.h and testing.cpp to pastebin or similar when asking for help as it makes the code a lot easier to read :)

 

One thing I have to comment on is your inclusion of "using namespace std" in the header file. This is a big no no, most people will tell you that the "using namespace" thing is just bad in general which isn't always true, but that is another discussion. If you are to use the "using namespace" you should only include it in your cpp file. This is mainly to keep from getting ambiguous reference errors. 

Link to comment
Share on other sites

Link to post
Share on other sites

13 hours ago, MSVSora said:

Sure, though first I should point out that your code wont work anyway for a couple of reasons. Maybe you are just testing atm but your addAnimal function in its current state will do nothing, except allocate new memory then delete the old.

 

Anyway to the main function it should look something like

 


int main()
{
	animalShelter shelter; //create new animalShelter
	
	//As your addAnimal function requires an animal we must first create one
	animalShelter::animal bob; //As you have your animal struct inside of animalShelter then we have to use the animalShelter scope, I would recommend moving the animal decleration to outside of the animalShelter class. 
	bob.name = "Bob";
	bob.age = 10;
	bob.breed = "Robot";
	bob.weight = 2000;
	bob.friendly = "No clue"; //Not sure what this is supposed to be but seems like something that should be a bool?
	bob.description = "Some random text here about Bob";

	shelter.addAnimal(bob); //This is rather weird to do considering you also require the input inside the addAnimal function
	shelter.displayAll(); //This will currently not display anything as you currently don't actually store the animal

	return 0;
}

 

Also I would recommend you post your testing.h and testing.cpp to pastebin or similar when asking for help as it makes the code a lot easier to read :)

 

One thing I have to comment on is your inclusion of "using namespace std" in the header file. This is a big no no, most people will tell you that the "using namespace" thing is just bad in general which isn't always true, but that is another discussion. If you are to use the "using namespace" you should only include it in your cpp file. This is mainly to keep from getting ambiguous reference errors. 

.cpp file

.h file

main .cpp file

These are what I currently have.  You're saying I should move the namespace line to the main.cpp files 

Link to comment
Share on other sites

Link to post
Share on other sites

26 minutes ago, ExplOregon said:

.cpp file

.h file

main .cpp file

These are what I currently have.  You're saying I should move the namespace line to the main.cpp files 

 

It will be easier for me to show you so I will make the changes and add comments to all the changes, then you can look through it and ask if you have any questions, will post back once it is done

Link to comment
Share on other sites

Link to post
Share on other sites

I got most of the error codes away now I'm just getting errors like this



testingmain.cpp:29:29: error: cannot call member function ‘void animalShelter::displayAll()’ without object
   animalShelter::displayAll();

Here is a quick screenshot

I realized the .h file names were wrong up top and made some other changes to call the functions in main

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, ExplOregon said:

I got most of the error codes away now I'm just getting errors like this

 



 

testingmain.cpp:29:29: error: cannot call member function ‘void animalShelter::displayAll()’ without object
   animalShelter::displayAll();

 

Here is a quick screenshot

I realized the .h file names were wrong up top and made some other changes to call the functions in main

In your main file you try to call functions from the animalShelter class without an animalShelter object which is why you are getting this error

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, MSVSora said:

In your main file you try to call functions from the animalShelter class without an animalShelter object which is why you are getting this error

When I do it without the animalShelter:: it says it is not declared in this scope

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, ExplOregon said:

When I do it without the animalShelter:: it says it is not declared in this scope

Please watch through this video :) https://thenewboston.com/videos.php?cat=16&video=17488

If you get time I would recommend watching through the whole video series, the guy goes through all the basics very thoroughly. The video linked should help you with the problem at hand ^^

Link to comment
Share on other sites

Link to post
Share on other sites

After having read through your code I am a bit confused as to what you are trying to do in a lot of the functions, I can't look much more at it tonight but if you want to PM me we can go over it in more detail tomorrow. I would really recommend you check out that tutorial series though as I think it will help you a lot with what you are currently trying to do as it will give you a better grasp of the basics :) 

Link to comment
Share on other sites

Link to post
Share on other sites

11 minutes ago, MSVSora said:

Please watch through this video :) https://thenewboston.com/videos.php?cat=16&video=17488

If you get time I would recommend watching through the whole video series, the guy goes through all the basics very thoroughly. The video linked should help you with the problem at hand ^^

 

2 minutes ago, MSVSora said:

After having read through your code I am a bit confused as to what you are trying to do in a lot of the functions, I can't look much more at it tonight but if you want to PM me we can go over it in more detail tomorrow. I would really recommend you check out that tutorial series though as I think it will help you a lot with what you are currently trying to do as it will give you a better grasp of the basics :) 

Thank you so much for all of your help, I appreciate it! I'll be sure to PM you if I still cannot

figure it out after the videos, I've come across those videos before and they do a great job

putting the concepts in simple terms. Thanks again!

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×