Filling Dynamically Allocated Array in C++ - c++

I am trying to fill up the multi-dimensional array using dynamic memory allocation and running into problem of how to determine the size of each array.
The sizes are also dynamically generated in the for loop, not sure how i can transport this knowledge into looping construct to tell the compiler when to stop.
Please dont answer the problem directly, just a direction needed so i can figure out on how to solve the problem of determining this,
for (int v = 0; v < sizeof(a[y]); v++)
int** a = new int*[n];
for (int i = 0; i < n; i++) {
int colcount;
cout << "Enter Size of Array for " << i << " : ";
cin >> colcount;
a[i] = new int[colcount];
}
// How to fill the matrix now
for (int y = 0; y < n; y++) {
for (int v = 0; v < sizeof(a[y]); v++) {
cout << "Enter Array Content [" << y << "][" << v << "] :";
cin >> a[y][v];
}
}
Update:
Got it working by bringing the for loop inside.
int** a = new int*[n];
for (int i = 0; i < n; i++) {
int colcount;
cout << "Enter Size of Array for " << i << " : ";
cin >> colcount;
a[i] = new int[colcount];
for (int v = 0; v < colcount; v++) {
cout << "Enter Array Content [" << i << "][" << v << "] :";
cin >> a[i][v];
}
}
Last Update:
To better track contents and privileges of template class, i ended up using vectors and with the help of community, here is how i came up.
int n;
cout << "Enter Num of Vectors: ";
cin >> n;
vector<vector <int> > mult_arr(n);
for (int i = 0; i < n; i++) {
int k;
cout << "Enter size for vec " << i << ":";
cin >> k;
mult_arr[i].resize(k);
for (int x = 0; x < k; x++) {
cout << "Enter Array Contents [" << i << "][" << x << "] :";
cin >> mult_arr[i][x];
}
}

You cannot know or find the size of a dynamic allocated array without actually holding the size in a variable. You can not use the classic sizeof(arr)/sizeof(type) to find the size because the sizeof() a pointer is just its type size and not the total array size. Use std::vector or keep tracking the sizes of each dynamic array.

Instead of using pointers to pointers to int, consider using a single allocation. It is easier and faster!
int * matrix = new int[width * height];
matrix[y * width + x] = 0;
delete [] matrix;

I took the liberty to rewrite your program to a more domatic C++ program (including a main function, so you can test it). Technically, this does solve the same problem, but instead of using new and delete, it uses std::vector, which should always be the first thing you should reach for.
Unless you have a very very good reason not to use vector, I advice you forget about new/delete. Know that it's there and get on with your life.
I realize this doesn't actually answer your question. I think it's too long for a comment so I'm providing it as answer instead.
#include <iostream>
#include <vector>
#include <string>
int get_an_integer(std::string message)
{
std::cout << message;
int n;
std::cin >> n;
return n;
}
int main()
{
std::vector<std::vector<int>> matrix;
matrix.resize(get_an_integer("Number of vectors:"));
for (auto& vector : matrix)
{
vector.resize(get_an_integer("Vector size:"));
for (auto& element : vector)
element = get_an_integer("Element value:");
}
for (auto v : matrix)
{
for (auto e : v)
std::cout << e << " ";
std::cout << '\n';
}
}
Notice how I don't have to keep track of anything and I don't really care about the explicit size of anything. Even the values of the elements aren't interesting.
I hope this helps you. If you have any questions, please ask.

You can memset to initialize an array. like
int *arr = new int[5];
fill(c, c + 5, 3); //fill(array, array+size, intialvalue)
cout<<c[4];
I hope this will help you.

Related

how to fix this code for giving me "expression did not evaluate to a constant"

I tried to write this code but it says expression did not evaluate to a constant. I learn that this is because VS does not allow an undeclared array, as "n" is not understood by VS. How can i fix this code with a declared array?
#include<iostream>
using namespace std;
int main()
{
int i, n;
cout << "Enter size of array:";
cin >> n;
int a[n];
cout << "Enter elements of array:" << endl;
for (i = 0; i < n; i++)
cin >> a[(i + n - 1) % n];
cout << "Result after left shift:" << endl;
for (i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
How can i fix this code with a declared array?
Option 1
Declare the array with sufficiently large size and make sure that n is less than or equal to the size before using the array.
int i, n;
int a[1000];
cout << "Enter size of array (less than or equal to 1000):";
cin >> n;
if ( n > 1000 )
{
// Deal with the problem.
}
else
{
// Use the array.
}
Option 2
Use std::vector.
int i, n;
cout << "Enter size of array:";
cin >> n;
std::vector<int> a(n);
Variable length arrays (VLAs) are not part of the C++ language, although some compilers (like g++) support them as an extension.
You should be using the std::vector container from the Standard Template Library, instead. Once declared and properly initialized, a std::vector can be used much like a plain array:
#include<iostream>
#include <vector>
using std::cout; using std::cin; using std::endl;
int main()
{
int i, n;
cout << "Enter size of array:";
cin >> n;
std::vector<int> a(n);
cout << "Enter elements of array:" << endl;
for (i = 0; i < n; i++)
cin >> a[(i + n - 1) % n];
cout << "Result after left shift:" << endl;
for (i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
You have to allocate the array on the heap like this:
int* a = new int[n];
But when you do heap allocations, always remember to delete the allocated memory after you are done using it:
delete[] a;
If you don't want to worry about deleting the memory, you can look into std::vector.

Some weird exception throws

The strange problem appears in my program. It is working, but in debugging it shows the "Exception thrown" in random places at the outputting
cout<<"Average value:"<<u3.apr();
_getch();
Sometimes, it even throws this error after the main function (Behind the {})
It is quite annoying because the program just closes after 3 seconds because of these errors.
(Maybe that's because of class, but I'm trying to learn it ;) )
Have tried already changing lines order, rewriting class name and array name.
#include <iostream>
#include <conio.h>
using namespace std;
class vid
{
private:
int i, j;
double rez, sum=0;
public:
int size;
double *arr = new double[size];
double apr()
{
for (i = 0; i < size; i++)
{
sum += (*(arr + i));
}
return sum / size;
}
};
int main()
{
vid u3;
cout << "Enter array length:";
cin >> u3.size;
for (int i = 0; i < u3.size; i++)
{
cout << "Enter array's " << i << " element:" << endl;
cin >> *(u3.arr+i);
}
cout << "Your array:" << endl;
for (int i = 0; i < u3.size; i++)
{
cout << *(u3.arr + i) << "\t";
}
cout << endl;
cout<<"Average value:"<<u3.apr();
_getch();
}
Thanks for any help ;)
arr is initialised when u3 is constructed.
But you didn't populate u3.size until later.
So, your array has indeterminate length (which is already UB), and your accesses later may be invalid.
You're going to have to manage your class's member a bit more cleverly!
Such classes generally have a "resize" function that performs the allocation per the requested size. Don't forget to safely kill any prior allocation, transplanting data if necessary. You can find online plenty of examples of a vector implementation.
Certainly renaming classes and randomly re-ordering the lines of your program's source code is not going to solve anything.
u3.size is not set until after u3 is constructed. By setting u3.size you can avoid this compiler-time error.
It seems that as an alternative solution, you might want to consider how to get rid of the new call and the need to write a destructor that will delete arr.
By creating a constructor that takes a size parameter AND by switching arr to a std::vector, you can allow the class to hold the vector and handle memory allocation and deallocation:
#include <iostream>
#include <vector>
using namespace std;
class vid
{
private:
int i, j;
double rez, sum=0;
public:
int size;
std::vector<double> arr;
// constructor requires size to be passed in;
// constructor initializes the arr array with the passed in size to zeroes.
vid(int argSize) : size(argSize), arr(argSize, 0.0){ }
double apr()
{
for (i = 0; i < size; i++)
{
sum += arr[i];
}
return sum / size;
}
};
int main()
{
uint size;
cout << "Enter array length:";
cin >> size;
vid u3(size);
for (int i = 0; i < u3.size; i++)
{
cout << "Enter array's #" << i << " element:" << endl;
cin >> u3.arr[i];
}
cout << "Your array:" << endl;
for (int i = 0; i < u3.size; i++)
{
cout << u3.arr[i] << "\t";
}
cout << endl;
cout<<"Average value:"<<u3.apr();
char ch;
cin >> ch;
}

Memory leak when printing 2D array

I have memory leak when i print my 2D array, i looped in data from a vector into a vector called grid
Some indexes in Grid is null for example grid[8][8] is null, but grid[1][1] has a value of 3.
When i display indexes of grid with null value gives me a memory leak.
Below are my code, Any recommendations will be appreciated!
void populateAppendixB(vector<string> cityLocation, int **grid, int col, int row) {
vector<int> data = appendixB_data(cityLocation);
vector<string> appendixB_coordinates = getCoordinates(cityLocation);
vector<int> x_value = returncolValue(appendixB_coordinates);
vector<int> y_value = returnrowValue(appendixB_coordinates);
//loop data into grid[][]
for (int i = 0; i < x_value.size(); i++) {
grid[x_value[i]][y_value[i]] = data[i];
}
cout << " ";
//Top outer Grid
for (int i = 0; i < col + 2; i++) {
cout << " # ";
}
cout << " # ";
cout << endl;
//end
//y-axis
for (int j = row; j >= 0; --j) {
cout << " " << j << " # ";
for (int i = 0; i <= col; ++i) {
//displaying data
if(grid[i][j] == 0) {
cout << " ";
}
else {
cout << grid[i][j] << " ";
}
}
//Right outer Grid
cout << "#";
cout << endl;
}
//Last row of #
cout << " ";
for (int i = 0; i < col + 2; i++) {
cout << " # ";
}
cout << " # ";
cout << endl;
cout << " ";
//x-Axis
for (int i = 0; i <= col; i++) {
cout << i << " ";
}
cout << endl;
}
You use grid[x_value[i]][y_value[i]] = data[i];, but will not fill all of the grid since you only fill in one value of each column of grid (you only do this loop: for (int i = 0; i < x_value.size(); i++) {). Unless the grid passed in is pre-filled in with 0's properly (impossible to tell given your submitted code), then this is probably undefined behavior.
Even if it is a pre-filled in 2d array, when you print the elements of grid, you iterate from [0, cols] and [0, rows], which is likely not what you want (that iterates cols+1 columns and rows+1 rows. So, at least that last value will be accessing memory that is probably not valid.
As previous comments mention, it's a better idea to just use std::vector (e.g. std::vector<std::vector<int>> while using .at(i).at(j) to access elements which make use of C++ exceptions rather than accessing bad memory) or even std::array which are better at preventing and catching many issues cleanly. If you're worried about speed, it's probably not a huge deal and you can avoid copies by e.g. passing by reference, wrapping things in smart pointers if applicable, move semantics, etc.
I solved my problem by setting all my 2D array values to { }, then populate the grid array with the values that i want specifically.
It solves the memory leak problem but i am not sure if it is a good practice.

Lesser number of columns of the second row "cuts off" a bigger number of columns of the first row

*Edit: Still, when input 3 columns for the 1st row and 2 columns for the 2th, in the output 1st row becomes 2-elemented as the first.
Problem with outputting dynamically allocated number of equipes with separately dynamically allocated number of columns (for number of catches for the each equip)... Namely, if I try to allocate 2 equipes and then for the first equip two "catches" of fish (two columns) and for second equip three catches of fish, everything is o.k.... but if I try input of smaller number of columns ("catches") for the second row (equip) then in the output the "excess" of the first row is "cutted off", so for example if there where a 3 columns input for the 1st row and 2 columns input for the second row, in the output there will be just two columns (indices of numbers) for the every of the two rows.
#include<iostream>
int main()
{
using namespace std;
int *sum;
int *a = new int;
int *b = new int;
cout << "Total number of equips: ";
cin >> *a;
// Allocate a two-dimensional 3x2 array of ints
int** ippArray = new int*[*a];
for (int i = 0; i < *a+1; ++i) {
ippArray[i] = new int[*b];
}
// fill the array
for (int i = 1; i < *a+1; ++i) {
cout << "Total number of catches for " << i << "th equip : ";
cin >> *b;
cout << "Equip number: " << i << endl;
for (int j = 1; j < *b+1; ++j) {
cout << "Catch number: " << j << endl;
cin >> ippArray[i][j];
ippArray[i][j];
}
}
// Output the array
for (int i = 1; i < *a+1; ++i) {
for (int j = 1; j < *b+1; ++j) {
cout << ippArray[i][j] << " ";
*sum = *sum + ippArray[i][j];
}
cout << endl;
}
cout << endl;
cout << "All catches of the all equipes: " << *sum-3;
// Deallocate
for (int i = 1; i < *a+1; ++i) {
delete [] ippArray[i];
}
delete [] ippArray;
// Keep the window open
cin.get();
return 0;
}
First, don't make your integers into pointers (int *a = new int;) unless they really need to be. It makes the code much harder to read, and if anyone has to maintain your code they'll call you an a-hole.
Second, int** ippArray = new int*[*a]; combined with multiple spots where you do this... for (int i = 1; i < *a+1; ++i) are bad. ippArray has valid references from 0 to *a, therefore it should be for (int i = 0; i < *a; ++i)
Edit: Try something like this http://ideone.com/4egQl3
Edit2: Also the standard advice...
{
std::vector<string> advice;
advice.push_back( "These will make your life easier" );
}
// No de-allocation needed!
Parts of your program that have undefined behaviour
Use of *b before you assign to it
Access out-of-bounds elements of all your arrays
Never initialise sum
Use of *sum before you assign to it
cleaned up, your code becomes
int main()
{
using namespace std;
int sum, a, b;
cout << "Total number of equips: ";
cin >> a;
typedef vector<vector<int> > vvint;
typedef vector<int> vint;
// Allocate a two-dimensional structure of ints
vvint ippArray(a);
// fill the array
for (vvint::size_t i = 0; i < a; ++i) {
cout << "Total number of catches for " << i+1 << "th equip : ";
cin >> b;
cout << "Equip number: " << i+1 << endl;
ippArray[i] = vint(b);
for (int j = 0; j < b; ++j) {
cout << "Catch number: " << j+1 << endl;
cin >> ippArray[i][j];
}
}
// Output the array
for (const vint & inner : ippArray) {
for (int num : inner) {
cout << num << " ";
sum += num;
}
cout << endl;
}
cout << endl;
cout << "All catches of the all equipes: " << sum;
cin.get();
return 0;
}

C++: Dynamically create array named after for loop iterator

Hey so I want to create n arrays (based off user input) of size x (also off user input). The way I was thinking of doing it was having a for loop perform n iterations and inside the loop ask the user for x. The problem is I'm not sure how to name the array using the variable n, I was thinking something like:
cout << "Enter n: ";
cin >> n
for (i = 0; i < n; i++)
{
cout << "Enter x: ";
cin >> x;
double*array+i;
array+i = new double[x]
}
To sum up my question is: can you create/name an array using a variable in C++?
Unfortunately, you can't do this in C++. Try something like this...
std::cout << "Enter n: ";
std::cin >> n
std::vector<std::vector<double> > arrays(n);
for (std::size_t i = 0; i < n; i++)
{
std::cout << "Enter x: ";
std::cin >> x;
arrays[i].reserve(x);
}
reserve only allocates, but does not construct the objects in the std::vector; if you want to construct them too, use resize.
PS Never use using namespace std; it makes your code harder to read and debug.
Since you are programming in C++, you should use STL containers (especially std::vector) instead of C-style arrays.
If you need to access an array by using the string that has been created in runtime, then you could use std::map< std::string, std::vector<double> >, which is pretty crazy idea though:
typedef std::vector<double> MyVector;
std::map<std::string, MyVector> myVectors;
// create an array:
std::string arrayName;
arrayName = std::string("someArray"); // could be: std::cin >> arrayName;
myVectors[arrayName] = MyVector(10, 1.23); // new vector of size 10
std::cout << myVectors["someArray"][4]; // prints 1.23
I'm not sure what exactly is what you are trying to achieve, but there are most likely more appropriate solutions. Is it really necessary to access these arrays via their names? I'm pretty sure that common std::vector< std::vector<double> > would suffice here.
Here's 3 solutions: the first is closest to your example code, the second is an improvement in order to be able to correctly retrieve the array elements within bounds, and the third is the reason why you are better served with vectors.
Solution 1:
It looks like you want your arrays to have names that are distinguishable by your loop iterator. Like Joe said, you could have an array of an array, so the inner arrays will be named array[0], array[1], ..., array[n - 1]. This will be achieved by using a pointer to pointer to double. Each of the inner pointers will be used to dynamically allocate arrays of double. Don't forget to delete the dynamically allocated memory.
#include <iostream>
int main()
{
unsigned int n;
std::cout << "Enter number of arrays: ";
std::cin >> n;
double** array = new double*[n];
for (int i = 0; i < n; ++i)
{
unsigned int size;
std::cout << "Enter size of array " << i << ": ";
std::cin >> size;
array[i] = new double[size];
for (int j = 0; j < size; ++j)
{
int element;
std::cout << "Enter element " << j << " of array " << i << ": ";
std::cin >> element;
array[i][j] = element;
}
}
for (int i = 0; i < n; ++i)
{
delete [] array[i];
}
delete[] array;
return 0;
}
Solution 2:
However, with the above code, you will have trouble accessing the elements of each inner array. Unless you memorized the size of each inner array you create with this, you might access something out of bounds. Therefore, an update to this code would be to add yet another array, let's call it sizeOfInnerArrays, where each of its element i keeps track of the size of inner array array[i]. Here's the update:
#include <iostream>
int main()
{
unsigned int n;
std::cout << "Enter number of arrays: ";
std::cin >> n;
double** array = new double*[n];
unsigned int* sizeOfInnerArrays = new unsigned int[n];
for (int i = 0; i < n; ++i)
{
std::cout << "Enter size of array " << i << ": ";
std::cin >> sizeOfInnerArrays[i];
array[i] = new double[sizeOfInnerArrays[i]];
for (int j = 0; j < sizeOfInnerArrays[i]; ++j)
{
int element;
std::cout << "Enter element " << j << " of array " << i << ": ";
std::cin >> element;
array[i][j] = element;
}
}
//prints out each array as curly-brace enclosed sets of doubles
for (int i = 0; i < n; ++i)
{
std::cout << "{";
for (int j = 0; j < sizeOfInnerArrays[i] - 1; ++j)
{
std::cout << array[i][j] << ", ";
}
std::cout << array[i][sizeOfInnerArrays[i] - 1] << "}" << std::endl;
}
// free dynamically allocated memory
for (int i = 0; i < n; ++i)
{
delete [] array[i];
}
delete[] array;
delete[] sizeOfInnerArrays;
return 0;
}
Solution 3:
However, that is too complicated, so you are better off using a container, like vector, as Joe suggested, whose data member keeps track of its size.
#include <iostream>
#include <vector>
int main()
{
unsigned int n;
std::cout << "Enter number of vectors: ";
std::cin >> n;
std::vector<std::vector<double> > myVec;
// ^ space between closing angle brackets not needed
// if using C++11 conforming compiler
for (int i = 0; i < n; ++i)
{
unsigned int size;
std::cout << "Enter size of vector " << i << ": ";
std::cin >> size;
std::vector<double> temp;
temp.reserve(size);
for (int j = 0; j < size; ++j)
{
double value;
std::cout << "Enter next value of vector " << i << ": ";
std::cin >> value;
temp.push_back(value);
}
myVec.push_back(temp);
}
for (int i = 0; i < myVec.size(); ++i)
{
std::cout << "{";
for (int j = 0; j < myVec.at(i).size() - 1; ++j)
{
std::cout << myVec.at(i).at(j) << ", ";
}
std::cout << myVec.at(i).back() << "}" << std::endl;
}
return 0;
}