c++:defining function which can work as growable array - c++

i want growable array for my project. I am trying to define a function that can give me replaced array with new size.I want some idea how can i do this.
int growarray[10];
int length =20;
//grow increase size of growarray to 20
void grow(int length){
}

std::vector would be the ideal way to do this, if you really want to code your own dynamic array you'll need to declare your array on the heap and do something like this...
int* growarray = new int[10];
and then to "expand" it...
int* temp = new int[20];
memcpy(temp, growarray, 10);
delete[] growarray;
growarray = temp;
when using this sort of technique you generally expand the array by a constant factor(usually 2 but some libraries use all sorts of different factors)

Related

Copy array then delete original

I have an array of a structure (with the parameters of name and number), and the initial array takes in elements from a document that I've made. The initial list size starts at 1000. When the list fills up, I call another method that I'm struggling with. I would like for it to copy the data into a new array that doubled the size, and then delete the old array.
If I name it: array1 and array2, I have my program use array1 throughout. I need help with the pointers that would get array2 to work as array1.
Is there a way to copy the array to a temp array of the same or new size, and then remake the initial array reassigning back to that? For this exercise, I can't use vectors. While I know how to use them, and that they solve this issue while being better, I'm trying to do it with only arrays.
using namespace std;
struct Information {
char functionality;
int SSN;
string name;
};
int numPeople = 1000;
//Gets called if the initial array (whatever size) is filled
void doubleArray(Information *array){
numPeople = numPeople * 2;
//Will now be the doubled array size
Information temp[numPeople]
for(int i = 0; i < numArray; i++){
temp[i].SSN = array[i].SSN;
temp[i].name = array[i].name;
}
//Normally makes it crash
delete[] array;
}
edit: This is what I currently have
void doubleArray(Information *person){
numPeople = numPeople * 2;
Information* temp = new Information[numPeople];
memcpy(temp, person, numPeople);
delete[] person;
person = temp;
}
It gets to numPeople = 1000 (the initial list size) but then crashes shortly after. Is the doubling array correct?
Arrays are fixed size. You cannot change the capacity of the original array.
{Use std::vector}
You can have a pointer to an array. And use the same pointer. When the array is full, you can allocate another array, copy old array items to new array, delete the old array and assign your array pointer to the new array.
{Did I mention std::vector?}
By the way, there is a data structure that performs resizing as necessary. If I recall correctly, it is std::vector. Try it out. :-)
Assuming you are using std::array (which you should be), then copying the array is very easy.
std::array<myStruct, 1000> array1{};
std::array<myStruct, 2000> array2{};
// codes...
std::copy(array1.begin(), array1.end(), array2.begin())
However, this is a specific scenario in which you only use these two arrays. It will not dynamically double the size of the array as you simply cannot do this dynamically with stack-based arrays, just like c arrays[].
What you can, and should, be using is std::vector<myStruct>. This will dynamically grow as you need it. Until you provide us with code and a more specific issue, this is the best advice that I can offer with the information provided.
If you aren't allowed to use std::vector, as one of your comments stated, then you'll want to look at dynamic allocation.
size_t sz = [whatever];
// Dynamically allocate an array of size sz.
T* T_array = new T[sz];
// Do whatever...
delete[] T_array; // new[] needs to be paired with delete[].
T_array = nullptr; // Not strictly necessary, but a good idea if you have more code after.
As the size doesn't need to be constant for a dynamic array, this will allow you to allocate memory as necessary. You can then use std::copy() to copy data from one array to the other, as Goodies mentioned.
[For more information on dynamic allocation, see here.]

How make a dynamic array using void** and void*?

I want to make a dynamic memory array function where in the arguments I can put in any type I want, the count, and the item I want. I've been googling and looking at YT videos, but none of them explain how to do just THAT, and when the item I want is a pointer. For example, I would have this:
struct Entity
{
int health;
int level;
int experience;
char* name;
}
Entity** entitylist = NULL;
int entitycount = 0;
Entity* CreateEntity(/*args for creating an entity*/)
{
Entity* newentity = malloc(sizeof(Entity));
// All of the entity creation stuff and at the end...
AddItemToList(&Entity, &newentity, &entitycount);
}
I know in the function I want to create I would need to pass in references to the specific list, but from that I'm pretty much clueless. I've tried to use malloc and realloc but either crashes the program or does nothing. And would new and delete work for this type of stuff?
And how would removing something like this work? I haven't seen anything on the internet yet about removing an item from a list, only adding them.
Thanks!
Using a double pointer for a data type such as int** with give you a dynamic 2D array, or a dynamic array of pointer objects, depending on your implementation, and a single int* is just a normal dynamic array. To full instantiate and allocate the memory for these, here's how you do it:
1D Dynamic array:
int* arr;
arr = new int[SIZE];
2D Dynamic Array:
int** arr;
arr = new int*[SIZE]; //<- stop here for 1D array of pointer objects
for (int i = 0; i < SIZE; i++)
arr[i] = new int[SIZE2];

Create dynamic array based on an array returned by a function

I'm currently trying to learn C++, and one of the training exercises I'm doing asks that I do the following:
Create a dynamic array, add 100 int values to it.
Write a function that calculates the square of each array element, and save this int value as position 100 + element_index in the array.
At the current moment I have created a dynamic array and filled it with pseudo-random values. What I want to do is to calculate the square of these random values, and "append" them at the end of the array.
The variable firstArray is defined earlier, but is set to be 100.
typedef int* intPtr;
...
...
srand((unsigned)time(0));
intPtr myArray;
myArray = new int[firstArray];
for (int i = 0; i < firstArray; i++)
ptr[i] = (rand() % 10);
This creates my initial dynamic array, and gives each location in the array a random value between 0 and 10.
If I don't have to use a function, I can easily create a new dynamic array, copy the first 100 values in, and then calculate the squares and place them at the end. I have an attempt at some pseudo-code for the exercise, but I'm unsure as how to properly implement it.
Create dynamic array of size 100, called myArray
Fill each indexed location with a random value between 0 and 10
Pass the dynamic array into a function
Function creates a new dynamic array of size 200
The values on location 0-99 from myArray are copied over
Calculate the square of the value on location n, and write it to location n+100
Return the dynamic array
Delete [] myArray
Create new dynamic array of size 200, called myArray
Copy the values from the array returned by my function into myArray
Delete the array returned from my function
My question relates to passing the information into a function, and returning the new information:
How do I create a function that I can pass a dynamic array into, and have it return another dynamic array?
If it is not possible to have this question answered, I would also very much like feedback on structure, information included in the question and if this is not the right type of question to ask, so I can ask better questions in the future.
Function that takes a dynamic array and returns a dynamic array (of ints) would have this signature:
int* newArray(int* array, int size);
An implementation would then start with:
int* newArray(int* array, int size)
{
int* ret = new int[size * 2]; // double the size
// stuff to populate ret
return ret;
}
int* myBiggerArray = newArray(myArray, firstArray);
// use myBiggerArray
delete [] myBiggerArray;
Also, stay away from typedefing things like int*. int* is already clear and concise enough.
I don't see any requirement that the array needs to be allocated twice. You can allocate all the memory once.
// Allocate all the memory.
intPtr myArray = new int[firstArray*2];
// Fill the first part with random numbers
for (int i = 0; i < firstArray; i++)
ptr[i] = (rand() % 10);

How can we modify the size of array in C++?

I have an array of characters allocated with new and i want to modify the size of the array. Can i use realloc function for that? What is the best way to do so?
No, you can't... realloc() can only be used with malloc()/free()
Best call for a new[] allocated array is to create a new one and then memcpy() the data from one to another.
Better way - use an std::vector or std::string instead of array if you know you'll need resizing. Internally they're pretty much the same array.
In C++ it is best to use the STL std::vector class for this kind of thing. Either that, or a std::string.
I have an array of characters allocated with new and i want to modify the size of the array.
You can't resize an array, you can only allocate a new, larger one, move the contents to the new array, and delete the old one.
Can i use realloc function for that?
If you used malloc to allocate the original array, yes. But that's usually a bad idea in C++, where you usually want to deal with arrays of non-trivial objects not raw memory.
What is the best way to do so?
Use std::string (or perhaps std::vector<char>) to manage a dynamic array of characters automatically. These also have the advantage of using RAII to reduce the risk of memory leaks and other memory management errors.
You can use realloc(), if your array is allocated dynamically(via malloc/calloc/realloc). If you have static array, you can't resize it.If you have allocated with new:
int* Copy = new int[newSize];
std::copy(oldCopy,oldCopy+size,Copy);
But the best way would be to use std::vector<type> from c++ standard library
As was said by others, you cannot resize the array that was allocated per se, but you can create a larger one, copy the content of the first array to the second and delete the first one.
Here's an example, using std::copy().
int main(int argc, char** argv) {
int* arr = new int[5];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
int* tmp = new int[10];
std::copy(arr, arr + 5, tmp);
std::copy(arr, arr, tmp + 5);
delete[] arr;
arr = tmp;
for(int i = 0; i < 10; i++) {
std::cout << arr[i] << "\n";
}
delete[] arr;
std::cin.get();
return 0;
}
This first creates an integer array and fills it. It then creates a larger array and fills it with the content of the first array twice and display that new larger array.
The principle is the same for an array of characters.
As the others have mentionned, your best bet in C++ is to use the standard library. For a resizable array of characters, you should probably use std::string or a vector of strings, but it's a bit overkill in some situations.

How to allocate memory for a static n-dimensional array in c++

What is the best way to allocate memory for an n-dimensional array in c++ at runtime? I am trying to read a matrix of values from a file, and depending on which file I read, the matrix could be any size. However, once the matrix is created, its size is static.
Since I don't know at compile-time what the size will be, I can't define it as int[a][b], so I was experimenting with using pointers to pointers like int**, but when I declare int** arr; arr[0][0] = 1 I get an error. I've experimented with other solutions as well. For example, I tried using one of the answers to Determine array size in constructor initializer, using int* arr; arr = new int[a], but it doesn't seem to work once I try to use it for two dimensions. Granted, I could be using it incorrectly, but the following block of code gives me a segfault:
int** arr;
(*arr) = new int[a];
edit: And of course, right after I ask the question, I find something semi-suitable in Need help regarding Dynamic Memory Allocation for two dimensional arrays in C++. I'd prefer not to do it this way, but it's definitely doable.
You would do it something like this (stolen from this answer):
int** ary = new int*[sizeX];
for(int i = 0; i < sizeX; ++i)
ary[i] = new int[sizeY];
Alternatively, you can do this:
int *ary = new int[sizeX*sizeY];
// ary[i][j] is then rewritten as
ary[i*sizeY+j]
It might remove the headache of pointer indirection.