C++ creating an array pointing to different arrays - c++

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.

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

Printing out an entire array multiple times

I am wondering how you can print out an entire array multiple times in C++. Say you have the following array:
arr1 = [1,2,5,6,7,8]
and you want to print it out n times such that the output would be:
1 2 5 6 7 8
1 2 5 6 7 8
1 2 5 6 7 8
If n would be equal to 3. You could just code some number of for loops if n is a static integer, but what if it's dynamic?
I know you need to use a for loop for printing out all the contents of an array, but I'm not sure what you would do if you want to get the above output.
If n is dynamic, it doesn't matter. You can have a loop that prints the array n times quite easily:
void printInts(int* arr, size_t size) {
// some printing logic
}
int main() {
int arr[] = {0,1,2,3,4,5,6,7,8};
int n = 3; // could be anything really
for(int i = 0; i<n; i++) {
printInts(arr, 9);
}
}
The value of n doesn't really matter here: it should print n times.
If you're asking how do we know the size of arr if it's a dynamic array, that's actually pretty easy too:
Until C++11:
size_t size = sizeof(arr)/sizeof(arr[0]);
After C++11 you can use:
size_t size = *(&arr + 1) - arr;
You could do this in main() or even in printInts() if you want.
Note: keep in mind you can't get the size of a pointer allocated dynamically easily. If you allocate with say new, you'll have to keep track of the size of the array yourself.
You can't. The size of an array allocated with new[] is not stored in any way in which it can be accessed. Note that the return type of new [] is not an array - it is a pointer (pointing to the array's first element). So if you need to know a dynamic array's length, you have to store it separately.
If what you're asking is how to get user input:
int n;
cin >> n;
for (int i = 0; i < n; i++) {
// print array
}
I think you know how to use for loop.
int rows;
int arr1 [5] = {1, 2, 3, 4, 5};
cout << "Enter number of rows? ";
cin >> rows;
for(int row=1; row<=rows;row++) {
for(int index=0;index<=4;index++) {
// print the array index here and space after a digit
}
// print line-break here
}

initializing a dynamic array to 0?

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

If we declare an array of four elements, can these elements store values?

In C++ if we declare an array of four elements, can these elements store values? I mean, if we declare the following array:
#include <iostream>
int main()
{
int a[4];
double res;
double avg;
avg = res = 0.0;
for(int i=0; i<4; i++)
{
cout<<"Please enter age ";
cin>> a[i];
}
for(int i=0; i<4; i++)
{
cout<< "You have entered these ages " <<a[i];
cout<<endl;
res += a[i];
}
avg = res/4;
cout<< "Total is "<<res <<endl;
cout<< "Avg is "<<avg;
}
this above program is a program with an integer (numeric) array, while in character array can we assign any value of the character array's elements?
Yes.
Array is a placeholder for the values of same type and no. of places are reserved during array declarion.
int a[3];
means it can store 3 ints. to be accessed as a[0], a[1] and a[2].
Now, you can see the problem you have in your loop:
for(int i=1; i<=4; i++)
{
cout<<"Please enter age ";
cin>> a[i];
}
a[0] remains empty
loop runs 4 times: a[1], a[2], a[3], a[4] and, last 2 indices are not reserved.
You can correct it as following:
for(int i=0; i<3; i++)
{
cout<<"Please enter age ";
cin>> a[i];
}
your other question:
while in character array can we assign any value of the character array's elements
Nope, Each index will store exactly one char.
char c[3];
will store exactly 3 chars. if you tried to use other indices it may result into undefined behaviour, segmentation fault. as you are trying to access memory that was not allocated to your process.
Yes, the declared elements are available to store values.
However, in your example you have only declared a 3-element array, which gives you array elements a[0], a[1], and a[2]. You are accessing array elements a[1], a[2], a[3], a[4], resulting in an out-of-bounds situation.
If you are asking whether it's possible to assign a value to an element of an array, then the answer is yes. All of the following is perfectly valid:
char a[10];
a[4] = 'x';
std::cin >> a[6];
Note however that your code contains errors:
You index a with indices 1 to 4. This means a must be at least 5 elements long; it's currently defined with length of 3.
#include <iostream.h> should be just #include <iostream>. <iostream.h> is pre-standard and obsolete.
C++ array indices are 0 based, so while not technically an error, you're ignoring the first element of your array. You should probably phrase your for loops as for (int i = 0; i < 4; ++i)

Passing a variable of type int[5][5] to a function that requires int**

I'd like to test a function that takes runtime-allocated multidimensional arrays, by passing it a hardcoded array.
The function has a signature of void generate_all_paths(int** maze, int size) and the array is defined as int arr[5][5] = {REMOVED}.
I'm not exactly sure how to properly coerce the array for the function (or if that is impossible).
This multi dimensional array topic unfortunately confuses so many C++ programmers. Well, here is the solution:
void generate_all_paths(int (*maze)[5], int size);
That is what the function declaration has to look like. An alternative, but fully equivalent is
void generate_all_paths(int maze[][5], int size);
Both are creating a parameter that is a pointer to an array of 5 integers. You can then pass your array of arrays of 5 integers to that function:
generate_all_paths(arr, 5);
Because your array's first element is an array of 5 integers, it will be converted automatically (implicitly) to a pointer to that first element when passed to that function.
In the comments, you have shown you are bound to an int**, because both your inner and outer dimension must have runtime values. A multi-dimensional array can not be used anymore. What you can do for testing purposes then is to create an array of pointers like this:
int store[5 * 5] = { ..... };
int *arr[5] = { store, store + 5, store + 10, store + 15, store + 20 };
Then, actually, you can have your function accept a int**. As the first element of you array then is a int*, it will be converted to a int** automatically. Another way of doing this is keeping the data in the 2 dimensional array, but just creating a "view" structured of pointers to that array:
int *arr[5] = { store[0], store[1], store[2], store[3], store[4] };
Where store is your int[5][5] array. Since store[n] accesses the n'th sub-array of that two-dimensional array and the element type of it is int, the pointer-converted type of it is int*, which will be compatible again.
You can write:
void display(char **a)
And then use a[i][j] to refer to elements in it.
The declaration char ** means "pointer to pointer to integer". To break it down into steps:
char *b = a[i];
That gets you a pointer to the first element of the i'th array in the array-of-arrays.
char c = b[j];
That gets you the j'th element in the array b.
The next problem you'll have is of allocating such an array-of-arrays.
char **arrayOfArrays = new char *[10];
for (int n = 0; n < 10; n++)
arrayOfArrays[n] = new char[20];
That allocates an array of 10 arrays, each "child" array having 20 characters.
In C/C++, array access syntax is just a way of retrieving a value some distance away from a pointer.
char *p = "Hello";
char *pl = p + 2; // get pointer to middle 'l'
char l = *pl; // fetch
char o = p[4]; // use array syntax instead
void display(char ** array)
should work. Also I don't think that it is a reserved word in standard C/C++.
And also, why is array a reserved word?
It isn't. You are probably using Visual Studio where it's displayed as a keyword due to its use in C++/CLI as a native managed type. However, this is irrelevant for C++ and Visual Studio is misleading in that regard.
As to your problem: You can simply pass a pointer-to-pointers-to-char and then pass your nested array directly (provided you are working with a dynamically allocated array):
void display(char** array) …
That said, your function assumes a fixed, known array length and some other details. Better would be to use a nested std::vector, or std::string (for instance). Using such existing data types makes your life much easier.
void display(std::vector<std::string> const& array) {
for (size_t i = 0; i < array.length(); ++i)
cout << array[i] << endl;
}
To take advantage of this, your calling code needs to be changed as well to use these data structures instead of plain C arrays on chars.
The Earwicker's answer is missing an important fact. What he is proposing is an array of arrays. For the first this wastes memory for the array of pointers ("char **arrayOfArrays = new char *[10]" is the creation point of this). For the second the array of chars may then not be a continuous block of memory, which is often a problem.
The only workaround in C++ is to create a one dimensional array and calculate the indexes when you need them.
char *b = new char[width*height];
then you can refer to element x,y (x is along width, y along height) like this
char c=b[width*y+x];
This may be however a bit slower than the solution above (measured on GCC 3.4.5), so if you are not interested in continuous memory (for example you always access the elements with [][], never by adding integer to a pointer and dereferencing it), then you should use the array af arrays. However, if you are interested in having the continuous memory, e.g. to pass it as initializer to an std::string object or to send it as a whole through a network, you should use the second one.
The best is to use pointers, but Borland C++ admits passing arrays as parameters for functions. Look at this code (includes: iostream and conio):
////////////////////////////////////////////
void ReceivedArray(char x[5]){
for (int i=0; i<5; i++ )
cout << x[i];
}
void main(){
char *x = new char[5];
for (int i=0; i<5; i++ )
x[i]='o';
ReceivedArray(x);
getchar();
}
///////////////////////////////////////////////////////////////
For passing 2D arrays (oops! some lines in spanish, sorry!):
(includes: iostream, stdlb, stdio and math)
/////////////////////////////////////////////////
using namespace std;
void ver(int x[][20]){
for(int i=0; i<15; i++) {
for(int j=0; j<20; j++) {
cout<< x[i][j] <<" "; }
cout << "\n"; }
}
void cambiar0(int x[][20]){ int n[255];
for (int i=255; i>=0; i--)
n[255-i]=i;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
for(int k=0; k<255; k++)
if(x[i][j]==n[k]) {
x[i][j]=k; break; }
}
int main(int argc, char* argv[]){
int x[15][20]; char a;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
x[i][j]=rand()%255;
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
cambiar0(x);
cout << "\n\n";
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
system("PAUSE"); return 0;
}
///////////////////////////////////
Hope this is what you meant.
arr is a pointer to the multi-dimesional array you have and is actually a pointer to an int. Now since your function accepts a pointer to an int pointer, you need to get the address of arr using: &arr and pass that to the function so that you will have this code:
To coerce the array: Pass &arr to the function.
To reference the array inside the func: *maze[x][y]