Create dynamic array based on an array returned by a function - c++

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);

Related

Dynamic array seems bigger than the dynamic size variable for it

I have class A, in it I have a dynamic array arr and a dynamic variable s which determines the size of the array. At the start of my main I use the constructor for class A which sets s to 2 and fills the arr with dummy objects. Now when I add objects to the array and sort it, objects seem to disappear.
The size of my array (so variable s) gets doubled when there is not enough space in the array, so no free slot available.
The way I display the array is by using a for loop with the limit i < s. So it should display all objects in the array.
Now when I add more objects and the array gets bigger, the previously "lost" objects start to appear again. So it seems like my array is bigger than the variable s, which dynamically determines the size.
How is that possible?
class A
private:
int *s = new int;
obj *arr = new obj[*s];
//triggers when trying to add an object to the array, but every place from
//arr[0] to arr[s-1] is taken by non dummy object
void A::resize {
*s *= 2;
//for loop that fills code with dummy objects
}
void A::display {
for (int i = 0; i < *s; i++) {
displayobject(i);
}
}
I had a very similar code last year in university and everything worked fine, can't find my mistake.
I would just use a vector, where i can easily use a for loop to go through the real size, but our prof wants us to use a dynamically alocated array.

Creating bidimensional array's size with the input values

First of all, happy new year!
So, I'd like to ask if I could use some input values as the size of a bidimensional array, for example:
I'd like to know, if instead of doing this:
const int N = 10;
const int M = 10;
typedef int IntMatrix[N][M];
Let's say that would be the max size of the array I could create, but then the user inputs that the size must have a size of 5x5. I know I could then use 5x5 as a limit when doing stuff, but could I do like the same, but using the input values as the dimension of the Matrix?
Something like:
cin >> N >> M;
And then use that as the MAX size of each dimension.
Thanks for your help!
No. The size of an array must be known at compile time and can not be determined at runtime as described in this tutorial for example. Therefore, the size of the array cannot depend on user input.
What you can do, is allocate an array dynamically and store it's address in a pointer. The size of a dynamic array can be determined at runtime. However, there is a problem. Only the outermost dimension of a dynamically allocated 2D array may be determined at runtime. You have 2 options: Either you allocate a flat array of size NxM where the rows are stored continuously one after the other and you calculate the index using maths. Or, you use an array of pointers and assign each pointer to a dynamically allocated array column. The first option is more efficient.
There is another problem. Dynamic memory management is hard, and it's never a good idea to do it manually even if you know what you're doing. Much less if you don't. There is a container class in the standard library which takes care of memory management of dynamic arrays. It's std::vector. Always use it when you need a dynamic array. Your options stay similar. Either use a flat, NxM size vector, or a vector of vectors.
The array should be dynamically allocatedn because array size should be known at compile-time. You can do this way:
int N,M; // Dimensions
int** intMatrix; // Array of array
std::cin << N << M;
intMatrix = new int*[N]; // Allocate N the row
for(int i=0; i<N; i++){
intMatrix[i] = new int[M]; // For each row, allocate the col
}
// aaaand don't forget to free memory like this:
for(int i=0; i<N; i++){
delete [] intMatrix[i];
}
delete [] intMatrix;

C++ Pointer of Array of Ints Initialization

I want to have an array accessible by all functions of a class.
I put the array as private variable in the header file.
private:
int* arrayName;
In the .cpp file where I implement the class, the constructor takes in an int value (size) and creates the array. The goal is to fill it up
ClassName::ClassName(int numElements){
arrayName = new int[numElements]; //make arrays the size of numElements
for(int i = 0; i<numElements; i++)
arrayName[i] = 0;
}
I feel like this is quite inefficient. I know you can do int array[5] = {0}; but how do you do it when you don't initially know the size.
If you want to zero-initialize a newed array, just do value-initialize it. This has the effect of zero-initializing its elements:
arrayName = new int[numElements]();
// ^^
But you really want to be using an std::vector<int>.
private:
std::vector<int> vname;
and
ClassName::ClassName(int numElements) : vname(numElements) {}
This way you don't have to worry about deleting an array and implementing copy constructors and assignment operators.
You can use the memset function:
memset(arrayName,0,sizeof(int)*numElements);
This void * memset ( void * ptr, int value, size_t num ); function sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char).
To use it you must include the string.h header file.
For more information: http://www.cplusplus.com/reference/cstring/memset/
What you want to do is progressively expand the array on demand.
arrayName = new int[numElements];
for(int i = 0; i<numElements; i++)
arrayName[i] = 0;
The above code (what you gave) will give you an array of size numElements, and THEN the for loop will fill it. This is allocated now, and can't, as I understand it, be simply or easily resized (memset will overwrite previously held values in the array).
You could copy the whole array over every time you want to resize it:
int * oldarr = new int[OldSize];
//fill your old array
int * newarr = new int[NewSize];
for(int i = 0; i<OldSize; i++)
newarr[i] = oldarr[i];
Other than that, you could make the array much larger, or you could use various STLs, such as std::vector. Vector can be increased with a simple push_back function, and allows [] operator access (like arr[5] and whatnot).
Hope this helps!

When allocating a dynamic array, are the previous elements deleted?

Title says it all more or less. When I need an (for the sake of this example) integer array for an unknown amount of values I know I can change it's size using new *array = new int[size]. Now my question is: If I have an array of a certain size, but I need to make it bigger, can I just use the new operator to expand it and will it still have all previously stored elements or would it be smarter to create a whole new array with a dynamic size, copy all elements from the previous array into the new one and delete[] the old array. Basically just swapping between the two arrays, whenever I need a new size.
Specifically I am asking whether or not this piece of code would work in the way it's intended to work
for(int i = 1; i < 10; i++){
int *array = new int[i];
array[i-1] = i;
}
My assumption is that this array will first be the size of 1 and store the value 1 at index 0. Then it will reallocate its size to 2 and store the value to at index 1 and so on until i is 9.
I guess to rephrase my question a bit better: Does an array initialized with new have to be populated with elements or will it copy the elements it had from before using the operator?
You can't resize the array in this way. You need to make a new array and then copy the old array into it. You can also try std::vector, which does what you want automatically.
If you want to use pointers rather than std::vector to change the size of your array, you can do it in this way.
int n = 100; // This will be the number of elements.
int *array1; // Pointer
array1 = new int[n]; // This will allocate your array with size n, so you will have 100 elements. You can combine this with the previous in int *array1 = new int[n];
So fill up the this array however you please...
Then you decide you want a 200 element array instead? You will need to create a different array in the same way.
int *array2 = new int[200];
You can use the for loop to copy array 1 into array 2. The for loop should iterate as many times as there are elements in array 1 (100).
for(int i = 0; i < 100; ++i)
array2[i] = array[1];
At this stage array2 is exactly the same as array1, but with 100 uninitialized elements at your disposal from [100] to [199].
You won't need array1 anymore, so at some point, you should call
delete [] array1;
Your assumption, by the way would not work, because on the first cycle of your loop, you create (or try to create) an array of i=1 element. Arrays start counting at 0, so your only single element is [0]. When i is at 0, what is i-1?
If you try to access array[-1], you'll probably crash. But why should you want to create 10 different arrays? new keyword creates an unrelated object, not overwrites the one with the same name.
Does an array initialized with new have to be populated with elements or will it copy the elements it had from before using the operator?
new[] allocates new array, completely independent from previous.
I know 3 ways to "make the array bigger":
As #ravi mentioned, don't mess with poinsters, use modern std::vector.
Make new array in new pointer, std::move elements from old array to the new one, and then delete[] old array.
Get rid of new[] & delete[], use old realloc with malloc & free.
You have to allocate new array and copy old array's data into that. This is how vector is implemented. Had there been better way of doing it, C++ standard community would have considered that.

dynamic allocation of rows of 2D array in c++

In c++, I can create a 2D array with fixed number of columns, say 5, as follows:
char (*c)[5];
then I can allocate memory for rows as follows
c = new char[n][5];
where n can be any variable which can be assigned value even at run time. I would like to know whether and how can I dynamically allocate variable amount of memory to each row with this method. i.e. I want to use first statement as such but can modify the second statement.
Instead of a pointer to an array, you'd make a pointer to a pointer, to be filled with an array of pointers, each element of which is in turn to be filled with an array of chars:
char ** c = new char*[n]; // array of pointers, c points to first element
for (unsigned int i = 0; i != n; ++i)
c[i] = new char[get_size_of_array(i)]; // array of chars, c[i] points to 1st element
A somewhat more C++ data structure would be a std::vector<std::string>.
As you noticed in the comment, dynamic arrays allocated with new[] cannot be resized, since there is no analogue of realloc in C++ (it doesn't make sense with the object model, if you think about it). Therefore, you should always prefer a proper container over any manual attempt at dynamic lifetime management.
In summary: Don't use new. Ever. Use appropriate dynamic containers.
You need to declare c as follows: char** c; then, allocate the major array as follows: c = new char*[n]; and then, allocate each minor array as follows: c[i] = new char[m]
#include <iostream>
using namespace std;
main()
{
int row,col,i,j;
cout<<"Enter row and col\n";
cin>>row>>col;
int *a,(*p)[col]=new (int[row][col]);
for(i=0;i<row;i++)
for(j=0;j<col;j++)
p[i][j]=i+j;
for(i=0;i<row;i++)
for(j=0;j<col;j++)
cout<<i<<" "<<j<<" "<<p[i][j]<<endl;
//printf("%d %d %d\n",i,j,p[i][j]);
}