dynamically allocate an Array - c++

I want to declare a 2D Array without an initial size. It keeps on giving me an error:
Error C2078: too many initializes.
I have tried to dynamically allocate my array but nothing worked out so far as I am not too familiar with dynamic allocation. My question is If there is a possible way to declare an Array without an initial size and if so what is the most efficient way to do it ?

I wrote a simple program using pointers, new and delete functions. You can add more functionality to it.
#include <iostream>
using namespace std;
int main()
{
int size;
cout << "Input size of 2D array : ";
cin >> size;
int *ptr; // Declare Pointer
ptr = new int[size*size]; // Allocate memory of all elements in 2D array
for (int i = 0; i < size*size; i++) {
*(ptr + i) = 0; // Initialize every element to 0
}
cout << "Printing the 2D Array" << endl << endl;
int iterSize = 0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
cout << *(ptr + iterSize) << " ";
}
cout << endl;
}
delete [] ptr; // ptr memory is released
return 0;
}
Here is the output initializing all elements to 0:

my question is If there is a possible way to declare an Array without an initial size and if so what is the most efficient way to do it ?
Sure, you could provide a vector of vectors to represent a 2D array (let's say of integer values):
std::vector<std::vector<int>> my2DArray;
Well, regarding efficiency maybe performance and memory fragmentation wise it's better to wrap a 1D vector kept internally with an interface that allows 2D coordinate access.
That would require you to know and specify the dimension limits though.
So if you really want to keep a 2D structure without initial size the above mentioned vector of vectors is the way to go.

Related

How do you build an array with certain elements from another array in C++?

Given a one-dimensional array with n integers and a whole number A,
list how many elements are larger than A
and build an array with these elements.
I'm having problems with the last part.
The answer is almost already in the question
(giving it here, assuming that the question is really as simple as it confusingly seems to me):
count the relevant elements, print/"list" that number
create a new std::array of that size
(consider asking whether using a std::vector is an option, it would allow doing this in a single pass)
(explicitly do NOT attempt to use the non-C++ construct of C-style VLA, variable length arrays, like std::cin>>n; int NewArray[n];)
go through the input array again and copy the relevant elements to the new array
count indexes in both arrays separatly, because the index in the first array will soon be larger than the index into the new array
Note:
I intentionally do NOT provide code, because I feel that the compromise described here should be applied: How do I ask and answer homework questions?
First you have to create two arrays (if you can use std::vectors, i think they will work nicely in this scenario) - first one as a base, and the second one for storing values larger than A.
Get input of A and n.
Use a for loop to put n values into the base array.
Use a for loop to check if baseArray[i] is bigger than A, if true - put baseArray[i] into the second array (if youre using std::vectors do it by push_back()).
Display the number of values higher than A by secondArray.size().
Without using the std::vector:
#include <iostream>
using namespace std;
int main()
{
int n;
int A;
int howManyBiggerThanA = 0;
cin >> n;
cin >> A; //you haven't specified how the n and A are supposed to be implemented so ill assume its going to happen this way
int *array = new int[n]; //creating an array with n integers
array[0] = A; //assigning A to the array as specified in the question - "and a whole number A"
for (int i = 1; i < n; i++)
{
array[i] = i; //filling the array with n integers of value 1 to n-1 (u havent specified what values are supposed to be inside this array)
}
for (int i = 0; i < n; i++)
{
if (array[i] > A)
{
howManyBiggerThanA++; //determining how many values are bigger than A
}
}
int *arrayForBiggerThanA = new int[howManyBiggerThanA]; //creating an array for values that are bigger than A
int assistant = 0;
for (int i = 0; i < n; i++)
{
if (array[i] > A)
{
arrayForBiggerThanA[assistant] = array[i]; //filling the second array with elements that are bigger than A
assistant++;
}
}
cout << "How many elements bigger than A: " << howManyBiggerThanA << endl;
cout << "Values bigger than A: ";
for (int i = 0; i < howManyBiggerThanA; i++)
cout << arrayForBiggerThanA[i] << ", ";
delete[] array;
delete[] arrayForBiggerThanA;
return 0;
}

Creating array size of passed value gives garbage value

int higher_element = arr[0];
for(int i = 0; i < length; i++)
if(arr[i] > higher_element)
higher_element = arr[i];
cout << "Higher element in an unsorted array :" << higher_element << endl;
int Hash[higher_element] = {0};
Here I want to create a new array of size higher_element and initialize it to 0 but array is not creating, only a garbage value is created.
The output of the higher element is 12.
Since you are using C++, I suggest you to use vector.
Here's the std::vector solution for your problem.
std::vector<int> Hash(higher_element);
Vectors initialize to 0 automatically. But for your clarification,
std::vector<int> Hash(higher_element,0);
You can only use const in declaring the array.
If you want to use a variable to define the size of the array, try this
int *Hash;
Hash = new int[higher_element];
Hope to help you.

Dynamically allocating memory

I am new to C++ and programming in general so i apologize if this is a trivial question.I am trying to initialize 2 arrays of size [600][600] and type str but my program keeps crashing.I think this is because these 2 arrays exceed the memory limits of the stack.Also,N is given by user so i am not quite sure if i can use new here because it is not a constant expression.
My code:
#include<iostream>
using namespace std;
struct str {
int x;
int y;
int z;
};
int main(){
cin>>N;
str Array1[N][N]; //N can be up to 200
str Array2[N][N];
};
How could i initialize them in heap?I know that for a 1-D array i can use a vector but i don't know if this can somehow be applied to a 2-D array.
How 2-or-more-dimensional arrays work in C++
A 1D array is simple to implement and dereference. Assuming the array name is arr, it only requires one dereference to get access to an element.
Arrays with 2 or more dimensions, whether dynamic or stack-based, require more steps to create and access. To draw an analogy between a matrix and this, if arr is a 2D array and you want access to a specific element, let's say arr[row][col], there are actually 2 dereferences in this step. The first one, arr[row], gives you access to the row-th row of col elements. The second and final one, arr[row][col] reaches the exact element that you need.
Because arr[row][col] requires 2 dereferences for one to gain access, arr is no longer a pointer, but a pointer to pointer. With regards to the above, the first dereference gives you a pointer to a specific row (a 1D array), while the second dereference gives the actual element.
Thus, dynamic 2D arrays require you to have a pointer to pointer.
To allocate a dynamic 2D array with size given at runtime
First, you need to create an array of pointers to pointers to your data type of choice. Since yours is string, one way of doing it is:
std::cin >> N;
std::string **matrix = new string*[N];
You have allocated an array of row pointers. The final step is to loop through all the elements and allocate the columns themselves:
for (int index = 0; index < N; ++index) {
matrix[index] = new string[N];
}
Now you can dereference it just like you would a normal 2D grid:
// assuming you have stored data in the grid
for (int row = 0; row < N; ++row) {
for (int col = 0; col < N; ++col) {
std::cout << matrix[row][col] << std::endl;
}
}
One thing to note: dynamic arrays are more computationally-expensive than their regular, stack-based counterparts. If possible, opt to use STL containers instead, like std::vector.
Edit: To free the matrix, you go "backwards":
// free all the columns
for (int col = 0; col < N; ++col) {
delete [] matrix[col];
}
// free the list of rows
delete [] matrix;
When wanting to allocate a 2D array in C++ using the new operator, you must declare a (*pointer-to-array)[N] and then allocate with new type [N][N];
For example, you can declare and allocate for your Array1 as follows:
#define N 200
struct str {
int x, y, z;
};
int main (void) {
str (*Array1)[N] = new str[N][N]; /* allocate */
/* use Array1 as 2D array */
delete [] Array1; /* free memory */
}
However, ideally, you would want to let the C++ containers library type vector handle the memory management for your. For instance you can:
#include<vector>
..
std::vector <std::vector <str>> Array1;
Then to fill Array1, fill a temporary std::vector<str> tmp; for each row (1D array) of str and then Array1.push_back(tmp); to add the filled tmp vector to your Array1. Your access can still be 2D indexing (e.g. Array1[a][b].x, Array1[a][b].y, ..., but you benefit from auto-memory management provided by the container. Much more robust and less error prone than handling the memory yourself.
Normally, you can initialize memory in heap by using 'new' operator.
Hope this can help you:
// Example program
#include <iostream>
struct str {
int x;
int y;
int z;
};
int main()
{
int N;
std::cin>>N;
str **Array1 = new str*[N]; //N can be up to 200
for (int i = 0; i < N; ++i) {
Array1[i] = new str[N];
}
// set value
for (int row = 0; row < N; ++row) {
for (int col = 0; col < N; ++col) {
Array1[row][col].x=10;
Array1[row][col].y=10;
Array1[row][col].z=10;
}
}
// get value
for (int row = 0; row < N; ++row) {
for (int col = 0; col < N; ++col) {
std::cout << Array1[row][col].x << std::endl;
std::cout << Array1[row][col].y << std::endl;
std::cout << Array1[row][col].z << std::endl;
}
}
}

segmentation fault with pointer array

I am a getting a segment fault when trying to input data for my array of pointers. Im pretty new to coding so any help would be great. My task was to make an array of pointers then display, swap them around and than sort them
#include <iostream>
using namespace std;
float getValueFromPointer(float* thePointer)
{
return *thePointer;
}
float* getMinValue(float* a, float* b)
{
if (*a < *b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int arraySize;
cout << "Enter the array size: ";
cin >> arraySize;
float** speed = new float*[arraySize]; // dynamically allocated array
for(int i = 0; i < arraySize; i++)
{
cout << "Enter a float value: ";
cin >> *speed[i];
}
// Core Requirement 2
for (int i = 0; i < arraySize; i++)
{
float value = getValueFromPointer(*speed+i);
cout << "The value of the element " << i << " is: ";
cout << value << endl;
}
//float *pointerToMin = getMinValue(&speed[0], &speed[arraySize - 1]);
//cout << *pointerToMin << endl;
delete [] speed;
speed = NULL;
return 0;
}
You’ve only allocated space for the outer array but you need to also allocate space for each of the internal floats.
So before calling this line:
cin >> *speed[i];
You need to first allocate space for it:
speed[i] = new float;
Your problem is that you've allocated an array of float pointers. You need to allocate an array of floats. So currently you have no memory allocated for the actual floats. If you do this, you'll allocate that memory:
float *speed = new float[arraySize];
You don't have any need for a 2D/jagged array that I can see. If you start with the code above, the compiler errors should lead you right in the direction. (Basically you will start removing * from a lot of places in your code.)
EDIT
Based on your requirement that I misunderstood, a possible approach is the following. The other answer (the one that isn't mine) makes sense in broader scenarios than this, but hopefully this is sort of another angle to think about that rather arbitrary problem you're trying to solve:
int main()
{
float *pFloats = new float[10];
float **ppFloats = new float*[10];
//assign float values and pointers to them in same loop
for (int i = 0; i < 10; i++)
{
pFloats[i] = i;
ppFloats[i] = &pFloats[i];
}
//swap two arbitrary pointers
float *pTemp = ppFloats[4];
ppFloats[4] = ppFloats[5];
ppFloats[5] = pTemp;
//print our float array
for (int i = 0; i < 10; i++)
printf("%f\n", pFloats[i]);
//print our float array *through* our pointers
for (int i = 0; i < 10; i++)
printf("%f\n", *ppFloats[i]);
delete[] ppFloats;
delete[] pFloats;
}
Ignore the hard-coded constants, etc...The point here is that I've created a contiguous memory area for the floats, and then created an array of float pointers on top of it. Note that I can sort my pointer array with zero impact on the original array. There are much smarter ways to do this, but...looks like you're learning about raw pointers, so...
Contrast with the other answer which creates jagged memory for the floats (1 at a time, on demand, not necessarily contiguous).

Expanding a dynamically allocated array

I have allocated an array as follows.
#include <iostream>
int main() {
const int first_dim = 3;
const int second_dim = 2;
// Allocate array and populate with dummy data
int** myArray = new int*[first_dim];
for (int i = 0; i < first_dim; i++) {
myArray[i] = new int[second_dim];
for (int j = 0; j < second_dim; j++) {
myArray[i][j] = i*second_dim + j;
std::cout << "[i = " << i << ", j = " << j << "] Value: " << myArray[i][j] << "\n";
}
}
// De-allocate array
for (int i = 0; i < first_dim; i++)
delete[] myArray[i];
delete[] myArray;
}
Let's say I want to add a 4th element to the first dimension, i.e. myArray[3]. Is this possible?
I've heard that Vectors are so much more efficient for this purpose, but I hardly know what they are and I've never used them before.
Yes, but in a very painful way. What you have to do is allocate new memory which now has your new desired dimensions, in this case 4 and 2, then copy all the contents of your matrix to your new matrix, and then free the memory of the previous matrix... that's painful. Now let's see how the same is done with vectors:
#include <vector>
using std::vector;
int main()
{
vector< vector <int> > matrix;
matrix.resize(3);
for(int i = 0; i < 3; ++i)
matrix[i].resize(2);
matrix[0][1] = 4;
//...
//now you want to make the first dimension 4? Piece of cake
matrix.resize(4);
matrix[3].resize(2);
}
HTH
edit:
some comments on your original code:
In C++ ALL_CAP_NAMES usually refer to macros (something you #define). Avoid using them in other contexts
why do you declare FIRSTDIM and SECONDDIM static? That is absolutely unnecessary. If a local variable is static it means informally that it will be the same variable next time you call the function with kept value. Since you technically can't call main a second sime this is useless. Even if you could do that it would still be useless.
you should wrire delete [] array[i]; and delete [] array; so the compiler knows that the int* and int** you're trying to delete actually point to an array, not just an int or int* respectively.
Let's say I want to add a 4th element to the first dimension, i.e. myArray[3]. Is this possible?
Yes, but it's a pain in the neck. It basically boils down to allocating a new array, just as your existing code does (hint: put it in the function and make the sizes arguments to that function) and copying compatible elements over.
Edit: One of the things that std::vector does for you is properly de-allocating you memory. In the code you have, failure to allocate one of the arrays along the 2nd dimension will result in a memory leak. A more robust solution would initialize pointers to 0 before performing any allocation. An exception block could then catch the exception and free whatever was partially allocated.
Because this code becomes complex quickly, people resort to allocating a single buffer and addressing using a stride or using a 1D array of 1D arrrays (i.e. std::vector of std::vectors).