initializing a dynamic array to 0? - c++

int main()
{
int arraySize;
int arrayMain[arraySize-1];
cout << "\n\nEnter Total Number of Elements in Array.\n\n";
cin >> arraySize;
arrayMain[arraySize-1]={0};
cout <<"\n\n" <<arrayMain;
return 0;
}
my compiler freezes when I compile the above code. I am confused on how to set a dynamic array to 0?

You use a std::vector:
std::vector<int> vec(arraySize-1);
Your code is invalid because 1) arraySize isn't initialized and 2) you can't have variable length arrays in C++. So either use a vector or allocate the memory dynamically (which is what std::vector does internally):
int* arrayMain = new int[arraySize-1] ();
Note the () at the end - it's used to value-initialize the elements, so the array will have its elements set to 0.

if you want to initialize whole array to zero do this ,
int *p = new int[n]{0};

If you must use a dynamic array you can use value initialization (though std::vector<int> would be the recommended solution):
int* arrayMain = new int[arraySize - 1]();
Check the result of input operation to ensure the variable has been assigned a correct value:
if (cin >> arraySize && arraySize > 1) // > 1 to allocate an array with at least
{ // one element (unsure why the '-1').
int* arrayMain = new int[arraySize - 1]();
// Delete 'arrayMain' when no longer required.
delete[] arrayMain;
}
Note the use of cout:
cout <<"\n\n" <<arrayMain;
will print the address of the arrayMain array, not each individual element. To print each individual you need index each element in turn:
for (int i = 0; i < arraySize - 1; i++) std::cout << arrayMain[i] << '\n';

Related

C++ creating an array pointing to different arrays

The inputs to this program are as follows:
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
I would like n to be an array that points to other integer arrays. So, n should essentially be {{1, 5, 4}, {1, 2, 8, 9, 3}}. If I wanted to access the 0th array and the 1st index, the value should return 5, and if I were to access the 1st array and the 3rd index, the value should be 9.
However, the values that this code returns are 32764 and 32764.
#include <cstdio>
#include <iostream>
using namespace std;
int main() {
int n_l; // integer variable that will hold the length of array n
int q_l; // integer variable that will hold the length of the number of queries
cin >> n_l >> q_l; // assigns values to the variables n_l and q_l
int *n[n_l]; // creates an array that will contain pointers
for (int i = 0; i < n_l; i++){ // loops through the length of array n
int amount; // declares the variable amount
cin >> amount; // assigns a value to the variable amount
int k[amount]; // creates one of the arrays that will be added to n
for (int x= 0; x < amount; x++){ // loops through the length of k and assigns a value to each index
cin >> k[x];
}
n[i] = k; // adds the array k to the position in array n
}
for (int i = 0; i < q_l; i++){
int arraynum;
int index;
cin >> arraynum >> index;
cout << n[arraynum][index] << endl;
}
}
cin >> n_l >> q_l; // assigns values to the variables n_l and q_l
int *n[n_l];
This isn't allowed in C++. The size of an array variable must be compile time constant. You can create dynamic arrays. Most convenient way is to use std::vector class template from the standard library.
The issue with your pointers is that the automatic arrays that you create in the loop are automatically destroyed at the end of the loop statement and the pointers in the array are all dangling (i.e. invalid) pointers to destroyed arrays. When you later indirect through the invalid pointers, the behaviour of the program is undefined.
You want multiple arrays. What's a good way to create multiple objects? Array is a good way to create multiple objects. So, in order to create multiple arrays, you can create an array of arrays. Or, since you want dynamic sizes, you can create a vector of vectors. Here is an example of how to create a vector of vectors:
std::vector<std::vector<int>> n(n_l);
for(auto& vec : n) {
int amount;
std::cin >> amount;
vec.resize(amount);
for(auto& i : vec) {
cin >> i;
}
}
You could create a vector of pointers to the arrays within the vectors in the vector of vectors, but that would be pointless. You don't need the pointers.
You are defining your array inside for loop which its scope will be limited in that loop, try allocate area with new for array and save the address of newly allocated area to your pointer array.
for (int i = 0; i < n_l; i++){ // loops through the length of array n
int amount; // declares the variable amount
cin >> amount; // assigns a value to the variable amount
int *k = new int[amount];
for (int x= 0; x < amount; x++){ // loops through the length of k and assigns a value to each index
cin >> k[x];
}
n[i] = k; // adds the array k to the position in array n
}
After you’re done with it, don’t forget to delete allocated area:
for(int i = 0; i < n_l; i++)
delete[] n[i];
For starters variable length arrays are not a standard C++ feature
int *n[n_l];
Instead you could use std::vector<int *>. Or you could use std::vector<std::pair<int, int *>> where the first element of the pair stores the number of elements in the dynamically allocated array and the second element of the pair stores the pointer to the dynamically allocated array.
Moreover the array will contain invalid pointers because the arrays declared in the for loop
int k[amount];
will not be alive after exiting the for loop.
So at least you have to allocate dynamically arrays in the for loop.
And you need to check whether an entered index is a valid for a given array before accessing an element of the dynamically allocated array.

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.

how to correctly use a dynamic array?

So I am trying to use a dynamic array for my program and I do not know if I am doing it right. Should I use const int or just an int only?
int size = 1;
int *num1 = new int [size];
int *num2 = new int [size];
or
const int size = 1;
int *num1 = new int [size];
int *num2 = new int [size];
If the size is a compile-time constant that you want to create an "array" from, then I suggest std::array, as in
std::array<int, 1> num1;
If the size isn't known at compile-time then use std::vector, as in
std::vector<int> num1(size);
And if you really have to use explicit dynamic allocation then opt for smart pointers like std::unique_ptr, like
auto num1 = std::make_unique<int[]>(size);
As for if the variable size should be const, constexpr, not qualified at all, or if you should possible use the literal value directly when allocating, then it really depends on use-case, value availability, and personal preference.
On another note, for a size you should rather use the size_t type instead of int. Most programmers will immediately understand that when you use size_t the variable is used to store a size. Otherwise if you use int it could be any arbitrary integer value. Furthermore, size_t is an unsigned type, so it doesn't allow negative numbers, which is one less cause of problems.
I've seen you ask a few questions about this now, so I want to show you the difference between having to resize a dynamic array and using std::vector, which packages all of the features you'd want in a dynamically-sized block of contiguous memory.
The following code is how to increase a dynamic array to hold user input. We don't know how long the user wants to input numbers for, so we have to keep resizing every time they enter a new number.
int number = 0;
std::size_t array_size = 0; // we need to track the size of the thing
int *array = nullptr; // nothing in here yet
std::cout << "Enter a number, non-number to exit: ";
while (std::cin >> number)
{
// we need to request more memory
++array_size;
int *new_array = new int[array_size];
// we have to copy the old array to the new array
// fun note: as pointed out in the comments below, using memcpy on
// either src or dest == nullptr is undefined behavior. Just goes to
// show how hard it is to get something like this correct.
// Don't do this when we have perfectly good STL containers!
std::memcpy(new_array, array, (array_size - 1) * sizeof(int));
// delete the old array, if it exists (we can safely call delete on a nullptr)
delete[] array;
// assign the new block of memory to array
array = new_array;
// add the retrieved element to array
array[array_size - 1] = number;
std::cout << "Enter a number, non-number to exit: ";
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// output the array
for (std::size_t i = 0; i < array_size; i++)
{
std::cout << array[i] << "\n";
}
// all done, delete the memory that was allocated
delete[] array;
array = nullptr; // not strictly required, but can prevent us from accidentally deleting the same block of memory twice, which would be bad
We can do the same thing using std::vector:
int number;
std::vector<int> vec; // this is a vector that holds ints, it tracks its own size and memmory
std::cout << "Enter a number, non-number to exit: ";
while (std::cin >> number)
{
vec.push_back(number); // all done
std::cout << "Enter a number, non-number to exit: ";
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
for (std::size_t i = 0; i < vec.size(); i++)
{
std::cout << vec[i] << "\n";
}
// or we can used range-based for loops, which are awesome
for (auto& v : vec)
{
std::cout << v << "\n";
}
Note that in the std::vector example, I'm outputting the contents of the std::vector twice, just to show that we have an option for iterating through a vector that is not available for an int *. We don't need to keep track of memory. We don't need to new and delete. When the current program scope exits (if this is a function, for example), the destructor of the std::vector is called and cleans up memory for us.
USE VECTORS!!!

Memory Location as last value in enlarged dynamic array [duplicate]

This question already has answers here:
Function does not change passed pointer C++
(4 answers)
Closed 5 years ago.
I am passing a dynamic array to a function with a value that is meant to be added to the array and when I enlarge and reset the array dynamically and iterate over the array I find the last value of the array is a garbage value rather than what is expected. I've looked at a few other posts on SO as well as some documentation and i'm stumped on what i'm doing wrong. I would prefer to use a vector, but my assignment requires a dynamic array unfortunately. Any thoughts? Thanks.
Post above is passing pointers to vectors by reference and has nothing to do with enlarging dynamic arrays
Main
cout << "Please enter the size of the array of integers you would like to create: ";
cin >> size;
cout << "\nPlease enter your integers:\n";
int *integerArray = new int[size];
//store values in array
for (int dynamicArrayDataCounter = 0; dynamicArrayDataCounter < size; dynamicArrayDataCounter++)
cin >> integerArray[dynamicArrayDataCounter];
cout << "\n Please enter the integer you would like to insert into this array: ";
cin >> userInt;
InsertIntegerToSortedList(integerArray, userInt, size);
//Print array for proof
for (int counterPrinter = 0; counterPrinter < size + 1; counterPrinter++)
cout << endl << integerArray[counterPrinter];
//Remove memory and repoint dangling pointer
delete [] integerArray;
integerArray = NULL;
return 0;
}
Function
void InsertIntegerToSortedList(int *integerArray, int userInteger, int size)
{
//Declare new array to add index position for integerArray
int *resizedArray = new int[size + 1];
bool numInserted = false;
for (int counter = 0; counter < size + 1; counter++)
{
if (integerArray[counter] < userInteger)
{
resizedArray[counter] = integerArray[counter];
}
else if ((integerArray[counter] > userInteger && integerArray[counter - 1] < userInteger) || integerArray[counter] == userInteger || (integerArray[counter] <= userInteger && size - counter == 1))
{
resizedArray[counter] = userInteger;
numInserted = true;
}
else if (numInserted)
resizedArray[counter] = integerArray[counter - 1];
}
//Store resizedArray values in integerArray
integerArray = resizedArray;
//Remove dynamic array on heap and repoint dangling pointer
delete[] resizedArray;
resizedArray = NULL;
}
In
void InsertIntegerToSortedList(int *integerArray, int userInteger, int size)
you are passing the pointer integerArray by value, hence at the exit of the function you end up not modifying it. Pass it by reference, like
void InsertIntegerToSortedList(int* & integerArray, int userInteger, int size)
Furthermore, as mentioned in the comments, you're doing it slightly wrong. First, copy the array elements into resizedArray. Next, you need to delete the old array,
delete[] integerArray;
and finally assign to the newly allocate array to integerArray
integerArray = resizedArray;
That's all is needed, now integerArray will point to the memory that was allocated via resizedArray. No need to set resizedArray to NULL, it is just a local variable that will cease to exist at the exit of the function. What you care about is just the address of the memory you allocated, and you already have that stored into integerArray pointer.