Two dimensional arrays error [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
#include<iostream>
using namespace std;
double NUMB_COLS = 3;
void readMatrix(int matr[] [3], int numb_rows, int numb_cols)
{
for (int i = 0; i<numb_rows; i++)
{
for (int j = 0; j < numb_cols; j++)
{
cout <<"[" << i << "] [" <<j <<"] =";
cin >> matr[i][j];
}
}
}
void printMatr(int matr[][3], int numb_rows, int numb_cols)
{
for (int i = 0; i < numb_rows; i++)
{
for (int j = 0; j < numb_cols; j++)
{
cout << "[" << i << "][" << j << "] = " << matr[i][j];
}
cout << endl;
}
}
int main()
{
int matr[5][10];
printMatr(matr, 4, 5);
readMatrix(matr, 4, 5);
return 0;
}
The error is
31 23 C:\Users\Windows\Desktop\programs\arrays2.cpp [Error] cannot convert 'int ()[10]' to 'int ()[3]' for argument '1' to 'void readMatrix(int (*)[3], int, int)'
What to do??

The first error is, that you pass a pointer to matr to a function expecting a different array layout. Remember that all ints in matr are consecutive in memory. Even if you did cast your matr to the expected type before passing it to the function, what was at position matr[0][7] in main() will end up in position matr[2][1] inside readMatrix().
The second error is, that your function accepts a column count, even though it already declared the column count to be 3. Such inconsistencies are an ample source of bugs, and should be avoided at all cost. Unfortunately, C++ forbids you to use dynamically sized array types, so you cannot just change your function declaration to
void readMatrix(int numb_rows, int numb_cols, int matr[numb_rows][numb_cols]) {
as you can in C.
The easiest way to fix your problem is probably to use std::vector<>.

You need to specify the correct subscripts.
void readMatrix(int matr[5][10], int numb_rows, int numb_cols)
a std::vector would be a lot easier in this case.

You defined the array in main as
int matr[5][10];
but in the functions the corresponding parameter is defined as
int matr[][3]
They are different types.
If you want to use in the functions only a part of the array int matr[5][10]; that is only 4 first rows and 5 first columns then you have to define the corresponding parameter of the functions the same way as the original array that is as
int matr[][10];
For example
void printMatr(int matr[][10], int numb_rows, int numb_cols)
Or you have to change code in main and write
int matr[5][3];
printMatr(matr, 5, 3);
readMatrix(matr, 5, 3);
Also take into account that you defined variable
double NUMB_COLS = 3;
but do not use it (thogh it should be defined having integral type).
If you would write
const int NUMB_COLS = 3;
and then use it in array definitions there would not be such an error. For example
#include<iostream>
using namespace std;
const int NUMB_COLS = 3;
void readMatrix(int matr[] [NUMB_COLS], int numb_rows, int numb_cols)
{
for (int i = 0; i<numb_rows; i++)
{
for (int j = 0; j < numb_cols; j++)
{
cout <<"[" << i << "] [" <<j <<"] =";
cin >> matr[i][j];
}
}
}
void printMatr(int matr[][NUMB_COLS], int numb_rows, int numb_cols)
{
for (int i = 0; i < numb_rows; i++)
{
for (int j = 0; j < numb_cols; j++)
{
cout << "[" << i << "][" << j << "] = " << matr[i][j];
}
cout << endl;
}
}
int main()
{
int matr[5][NUMB_COLS];
printMatr(matr, 5, NUMB_COLS);
readMatrix(matr, 5, NUMB_COLS);
return 0;
}
You can assign NUMB_COLS any number including 10 used in your original code. The code I showed will not depend on "magic numbers". It uses only named constant NUMB_COLS

Related

C++: Error while allocating memory for a two dimensional array using functions

I am trying to understand passing by reference and passing by value. In this program I have a two dimensional array which is declared in main and whose size is allocated in a function. In the allocate2DArrayRef() function, I obtain the two sizes and dynamically allocate and initialize the array Array2D.
Now I am trying to understand how to do the same by pointers. I have written another function allocate2DArrayPtr() in where I pass a pointer to the two dimensional array, get the value of the sizes - sizeX and sizeY and then allocate the memory to the variable secArray2D.
When I run the program it hangs when I try to print out secArray2D. I am assuming this implies that the function allocate2DArrayPtr() has not been successful in dynamically allocating memory to the array secArray2D.
My final goal is to write a program which has a function that dynamically allocated memory and initializes multiple arrays of various dimensions which are read from an input file. I know I can expand on passing by reference function allocate2DArrayRef() to achieve my goal. But I am curious to learn why my function allocate2DArrayPtr() is not working as I want to be clear on how to pass by pointers also. I do know how to change allocate2DArrayPtr() to return a pointer but I would like to pass the array as a parameter.
I am running the program on windows 7 using Codeblocks 13.12 IDE.
#include <iostream>
using namespace std;
void allocate2DArrayRef(int **&, int &, int &);
void allocate2DArrayPtr(int ***, int *, int *);
int main()
{
int sizeX, sizeY;
int **Array2D;
allocate2DArrayRef(Array2D, sizeX, sizeY);
for(int i=0; i< sizeX; i++)
{
for(int j=0; j< sizeY; j++)
{
cout << "Array2D[" << i << "][" << j << "]:" << Array2D[i][j] << endl;
}
}
cout << endl << endl;
int **secArray2D;
allocate2DArrayPtr(&secArray2D, &sizeX, &sizeY);
for(int i=0; i<sizeX; i++)
{
for(int j=0; j<sizeY; j++)
{
cout << "secArray2D[" << i << "][" << j << "]:" << secArray2D[i][j] << endl;
}
}
return 0;
}
void allocate2DArrayRef(int **&locArray, int& indexFirst, int& indexSecond)
{
indexFirst = 4;
indexSecond = 5;
locArray = new int*[indexFirst];
for(int i=0; i<indexFirst ; i++)
{
locArray[i] = new int[indexSecond];
for(int j=0; j<indexSecond; j++)
{
locArray[i][j] = i*j;
}
}
}
void allocate2DArrayPtr(int ***locArray, int *indexFirst, int *indexSecond)
{
*indexFirst = 2;
*indexSecond = 3;
int **temp = *locArray;
temp = new int*[*indexFirst];
for(int i=0; i<(*indexFirst) ; i++)
{
temp[i] = new int[*indexSecond];
for(int j=0; j<(*indexSecond); j++)
{
temp[i][j] = i+j;
}
}
}
The reason allocate2DArrayPtr does not work is you never set locArray to point to the array you create in the function. This means when you return from the function secArray2D still is uninitialized.
Adding
*locArray = temp;
To the end of allocate2DArrayPtr will fix the problem.
Or you can reference your to temp like this:
int **&temp = *locArray;

c++ twodimensional array passed to function

I like to pass a two dimensional array to a function to print it.
Here is my code so far. As you can see on the comment it does not compile, because of an incompatible type.
QUESTION
How can I pass the two dimensional array to printIt ?
If I adjust it to printIt(int a(*)[50][50]) I get the another error during compilation, because returning array is not allowed
using namespace std;
void printIt(int a[50][50]);
int main(int args, char *argv[])
{
int a[50][50];
int j = 0;
for (int i = 1; i < 6; i++)
{
a[i][j] = i;
// the same should be printed out inside printIt
cout << " " << a[i][j];
// not compiling
// argument of type int is incompatible with int(*)[50]
printIt(a[i][j]);
}
}
void printIt( int a[50][50] )
{
cout << " " << a[50][50];
}
Given
int a[50][50];
a[i][j] evaluates to an int.
a[i] evaluates to int [50], an array of 50 integers. If used as an argument to a function call, a[i] decays to a int* in most cases. In rare cases it converts to int (&)[50].
If used as an argument to a function call, a decays to int (*)[50] in most cases. In rare cases it converts to int (&)[50][50].
In your case, the function declaration
void printIt(int a[50][50]);
is equivalent to
void printIt(int a[][50]);
and
void printIt(int (*a)[50]);
Hence, using
printIt(a);
is the right method of calling the function.
However
Given the way you are using the argument in printIt, you probably meant to use:
void printIt(int num)
{
cout << " " << num;
}
After that, it OK to use:
printIt(a[i][j]);
in main.
Because a[i][j] in an integer, it is a value. You are passing a value not an double array Your code should look like that :
#include <iostream>
using namespace std;
void printIt(int a)
{
cout << " " << a;
}
int main(int args, char *argv[])
{
int a[50][50];
int j = 0;
for (int i = 1; i < 6; i++)
{
a[i][j] = i;
// the same should be printed out inside printIt
cout << " " << a[i][j];
// not compiling
// argument of type int is incompatible with int(*)[50]
printIt(a[i][j]);
}
}

Deleting element from an array in c++

I have read others posts, but they don't answer my problem fully.
I'm learning to delete elements from an array from the book and try to apply that code.
As far as I can grasp I'm passing array wrong or it is sending integer by address(didn't know the meaning behind that).
#include <iostream>
#include <cstdlib>
using namespace std;
void delete_element(double x[], int& n, int k);
int main()
{
// example of a function
int mass[10]={1,2,3,45,12,87,100,101,999,999};
int len = 10;
for(int i=0;i<10;i++)
{
cout<<mass[i]<<" ";
};
delete_element(mass[10],10&,4);
for(int i=0;i<10;i++)
cout<<mass[i]<<" ";
return 0;
}
void delete_element(double x[], int& n, int k)
{
if(k<1 || k>n)
{
cout<<"Wrong index of k "<<k<<endl;
exit(1); // end program
}
for(int i = k-1;i<n-1;i++)
x[i]=x[i+1];
n--;
}
There are a couple of errors in your code. I highlight some of the major issues in question 1-3:
You call exit, which does not provide proper cleanup of any objects since it's inherited from C. This isn't such a big deal in this program but it will become one.
One proper way too handle such an error is by throwing an exception cout<<"Wrong index of k "<< k <<endl;
exit(1);
Should be something like this:
throw std::runtime_error("invalid index");
and should be handled somewhere else.
You declare function parameters as taking a int& but you call the function like this: delete_element(mass[10],10&,4); 10& is passing the address of 10. Simply pass the value 10 instead.
You are "deleting" a function from a raw C array. This inherently doesn't make sense. You can't actually delete part of such an array. It is of constant compile time size created on the stack. The function itself doesn't do any deleting, try to name the functions something more task-oriented.
You are using C-Arrays. Don't do this unless you have a very good reason. Use std::array or std::vector. These containers know their own size, and vector manages it's own memory and can be re sized with minimal effort. With containers you also have access to the full scope of the STL because of their iterator support.
I suggest you rewrite the code, implementing some type of STL container
Line 15: syntax error
you can't pass a number&
If you want to pass by reference, you need to create a variable first, like:
your delete_element function signature conflicts with your declared arrays. Either use a double array or int array and make sure the signatures match.
delete_element(mass, len , 4);
when you write the name of an array without the brackets, then it's the same as &mass[0]
ie. pointer to the first element.
complete changes should be:
#include <iostream>
#include <cstdlib>
using namespace std;
void delete_element(int x[], int& n, int k);
int main(){
// example of a function
int mass[10] = { 1, 2, 3, 45, 12, 87, 100, 101, 999, 999 };
int len = 10;
for (int i = 0; i<10; i++){ cout << mass[i] << " "; };
cout << endl;
delete_element(mass, len , 4);
for (int i = 0; i<10; i++)cout << mass[i] << " ";
cout << endl;
cin.ignore();
return 0;
}
void delete_element(int x[], int& n, int k){
if (k<1 || k>n){
cout << "Wrong index of k " << k << endl;
exit(1); // end program
}
for (int i = k - 1; i<n - 1; i++)
x[i] = x[i + 1];
n--;
}
There are a couple of mistakes in your program.
Apart from some syntax issues you are trying to pass an int array to a function which wants a double array.
You cannot pass a lvalue reference of a int literal. What you want is to pass a reference to the length of the int array. see also http://en.cppreference.com/w/cpp/language/reference.
Here is an updated version of your program.
#include <iostream>
#include <cstdlib>
using namespace std;
void delete_element(int x[], int& n, int k);
int main() {
// example of a function
int mass[10] = { 1,2,3,45,12,87,100,101,999,999 };
int len = 10;
for (int i = 0;i < len;i++)
cout << mass[i] << " "; ;
cout << endl;
delete_element(mass, len, 4);
for (int i = 0;i < len;i++) // len is 9 now
cout << mass[i] << " ";
cout << endl;
return 0;
}
void delete_element(int x[], int& n, int k) {
if (k<1 || k>n) {
cout << "Wrong index of k " << k << endl;
exit(1); // end program
}
for (int i = k - 1;i<n - 1;i++)
x[i] = x[i + 1];
n--;
}
Although it does not answer your question directly, I would like to show you how you can use C++ to solve your problem in a simpler way.
#include <vector>
#include <iostream>
void delete_element(std::vector<int>& v, const unsigned i)
{
if (i < v.size())
v.erase(v.begin() + i);
else
std::cout << "Index " << i << " out of bounds" << std::endl;
}
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7};
delete_element(v, 4);
for (int i : v)
std::cout << i << std::endl;
return 0;
}
You cannot delete elements from an array, since an array's size is fixed. Given this, the implementation of delete_element can be done with just a single call to the appropriate algorithm function std::copy.
In addition, I highly suggest you make the element to delete a 0-based value, and not 1-based.
Another note: don't call exit() in the middle of a function call.
#include <algorithm>
//...
void delete_element(int x[], int& n, int k)
{
if (k < 0 || k > n-1 )
{
cout << "Wrong index of k " << k << endl;
return;
}
std::copy(x + k + 1, x + n, x + k);
n--;
}
Live Example removing first element
The std::copy call moves the elements from the source range (defined by the element after k and the last item (denoted by n)) to the destination range (the element at k). Since the destination is not within the source range, the std::copy call works correctly.

C++ Passing Dynamic Array Determined by Parameter

This function has been asked a few times on here but I am interested in a particular case. Is it possible to have the size of the array passed defined by an additional argument?
As an example, let's say I want a function to print a 2D array. However, I the array may not have the same dimensions every time. It would be ideal if I could have additional arguments define the size of that array. I am aware that I could easily switch out the n for a number here as needed but if I have more complex functions with separate header files it seems silly to go and edit the header files every time a different size array comes along. The following results in error: use of parameter 'n' outside function body... which I understand but would like to find some workaround. I also tried with g++ -std=c++11 but still the same error.
#include <iostream>
using namespace std;
void printArray(int n, int A[][n], int m) {
for(int i=0; i < m; i++){
for(int j=0; j<n; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
int main() {
int A[][3] = {
{1,2,3},
{4,5,6},
{7,8,9},
{10,11,12}
};
printArray(3, A, 4);
return 0;
}
Supposedly, this can be done with C99 and also mentioned in this question but I cannot figure out how with C++.
This works:
template<size_t N, size_t M>
void printArray( int(&arr)[M][N] ) {
for(int i=0; i < M; i++){
for(int j=0; j < N; j++) {
std::cout << A[i][j] << " ";
}
std::cout << std::endl;
}
}
if you are willing to put the code in a header file. As a bonus, it deduces N and M for you.

c++ error: invalid types 'int[int]' for array subscript

Trying to learn C++ and working through a simple exercise on arrays.
Basically, I've created a multidimensional array and I want to create a function that prints out the values.
The commented for-loop within Main() works fine, but when I try to turn that for-loop into a function, it doesn't work and for the life of me, I cannot see why.
#include <iostream>
using namespace std;
void printArray(int theArray[], int numberOfRows, int numberOfColumns);
int main()
{
int sally[2][3] = {{2,3,4},{8,9,10}};
printArray(sally,2,3);
// for(int rows = 0; rows < 2; rows++){
// for(int columns = 0; columns < 3; columns++){
// cout << sally[rows][columns] << " ";
// }
// cout << endl;
// }
}
void printArray(int theArray[], int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}
C++ inherits its syntax from C, and tries hard to maintain backward compatibility where the syntax matches. So passing arrays works just like C: the length information is lost.
However, C++ does provide a way to automatically pass the length information, using a reference (no backward compatibility concerns, C has no references):
template<int numberOfRows, int numberOfColumns>
void printArray(int (&theArray)[numberOfRows][numberOfColumns])
{
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}
Demonstration: http://ideone.com/MrYKz
Here's a variation that avoids the complicated array reference syntax: http://ideone.com/GVkxk
If the size is dynamic, you can't use either template version. You just need to know that C and C++ store array content in row-major order.
Code which works with variable size: http://ideone.com/kjHiR
Since theArray is multidimensional, you should specify the bounds of all its dimensions in the function prototype (except the first one):
void printArray(int theArray[][3], int numberOfRows, int numberOfColumns);
I'm aware of the date of this post, but just for completeness and perhaps for future reference, the following is another solution. Although C++ offers many standard-library facilities (see std::vector or std::array) that makes programmer life easier in cases like this compared to the built-in array intrinsic low-level concepts, if you need anyway to call your printArray like so:
printArray(sally, 2, 3);
you may redefine the function this way:
void printArray(int* theArray, int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x * numberOfColumns + y] << " ";
}
cout << endl;
}
}
In particular, note the first argument and the subscript operation:
the function takes a pointer, so you pass the name of the multidimensional array which also is the address to its first element.
within the subscript operation (theArray[x * numberOfColumns + y]) we access the sequential element thinking about the multidimensional array as an unique row array.
If you pass array as argument you must specify the size of dimensions except for the first dim. Compiler needs those to calculate the offset of each element in the array. Say you may let printArray like
void printArray(int theArray[][3], int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}