This question already has answers here:
How to pass a 2D array by pointer in C?
(5 answers)
Closed 2 years ago.
I am trying to pass two dimensional array in function, but is has two errors which I don't know why. I have some articles about passing two dimensional array in function but also can't understand why I fail.
#include <iostream>
using namespace std;
// prototypes
void matrixSwap(double** matrix, int rows, int columns);
int main()
{
const int ROWS = 5;
const int COLUMNS = 5;
double matrix[ROWS][COLUMNS] =
{
{ 1, 2, 3, 4, 5},
{ 6, 7, 8, 9, 0},
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20},
{21, 22, 23, 24, 25}
};
matrixSwap(matrix, ROWS, COLUMNS);
/* it says
1) argument of type "double (*)[5U]" is incompatible with parameter of type "double **"
2) 'void matrixSwap(double *[],int,int)': cannot convert argument 1 from 'double [5][5]' to 'double *[]'
*/
}
void matrixSwap(double** matrix, int rows, int columns) {}
The multidimensional double array matrix you're trying to pass in the function matrixSwap() to the argument double**, actually doesn't represents a multidimensional array.
Use arrays correctly as shown:
#include <iostream>
using namespace std;
const unsigned short MAXROWS = 5;
// prototypes
void matrixSwap(double matrix[][MAXROWS], int rows, int columns);
int main()
{
const int ROWS = 5;
const int COLUMNS = 5;
double matrix[ROWS][COLUMNS] =
{
{ 1, 2, 3, 4, 5},
{ 6, 7, 8, 9, 0},
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20},
{21, 22, 23, 24, 25}
};
matrixSwap(matrix, ROWS, COLUMNS);
}
void matrixSwap(double matrix[][MAXROWS], int rows, int columns) {}
Just changed into [][MAXROWS] where MAXROWS contains an unsigned integer of value 5.
The declaration:
void matrixSwap(double matrix[][MAXROWS], int rows, int columns)
is equivalent to:
void matrixSwap(double (*matrix)[MAXROWS], int rows, int columns)
Notice that here I've used *matrix and then appended [MAXROWS] which does the same job as matrix[][MAXROWS].
So you may do the same thing in another way as follows:
void matrixSwap(double (*matrix)[MAXROWS], int rows, int columns) {
for (int i = 0; i < columns; i++) {
for (int j = 0; j < rows; j++) {
std::cout << matrix[i][j] << ' ';
}
std::cout << std::endl;
}
}
This will give you the output:
1 2 3 4 5
6 7 8 9 0
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
To see if the matrix is successfully passed into the function by the new argument.
Related
I was following internet tutorials on this topic, but I have the following situation:
I have a function with the following signature:
void func(long& rows, long& columns, int array[][columns]);
and I'm trying to use the function like this:
int matrix[5][4] = {0, -1, 2, -3,
4, -5, 6, -7,
8, -9, 10, -11,
12, -13, 14, -15,
16, -17, 18, -19};
long rows = 5;
long columns = 4;
func(rows, columns, matrix);
^--- 'No matching function for call to 'func''
What is the problem? Why can't it call the function?
Variable length arrays is not a standard C++ features.
You could declare the function and the array the following way
const size_t columns = 4;
void func( size_t rows, const int array[][columns]);
//...
int matrix[][columns] = { { 0, -1, 2, -3 },
{ 4, -5, 6, -7 },
{ 8, -9, 10, -11 },
{ 12, -13, 14, -15 },
{ 16, -17, 18, -19 } };
func( sizeof( matrix ) / sizeof( *matrix ), matrix);
//...
void func( size_t rows, const int array[][columns] )
{
std::cout << rows << columns << array[0][1];
}
Pay attention to that as the number of columns is well-known there is no sense to pass it to the function. And moreover there is no sense to pass the number of rows and columns by reference.
Have you actually defined func in your program?
The following source code compiles and works fine for me
#include <iostream>
#define ROW 5
#define COLUMN 4
void func(long &rows, long &columns, int array[][COLUMN]);
int main()
{
int matrix[ROW][COLUMN] = {0, -1, 2, -3,
4, -5, 6, -7,
8, -9, 10, -11,
12, -13, 14, -15,
16, -17, 18, -19};
long rows = 5;
long columns = 4;
func(rows, columns, matrix);
return 0;
}
void func(long &rows, long &columns, int array[][COLUMN])
{
std::cout << rows << columns << array[0][1];
}
I am using gcc compiler on ubuntu 16 , when I am printing value garbage value is getting displayed
#include <bits/stdc++.h>
int Arrayprint(int r, int l, unsigned int* q)
{
r = 3;
l = 4;
for (int i = 0; i < r; i++) {
for (int j = 0; j < l; j++) {
cout << *(q + sizeof(unsigned int) * (i * l + j)); //Garbage getting diplay
cout << *(q + i + j); //this working
cout << "\t";
}
}
cout << "size of unsigned int : " << sizeof(unsigned int); //4
cout << "size of int : " << sizeof(int); //4
}
int main()
{
unsigned int image[R][L] = { { 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 } };
unsigned int* q = (unsigned int*)image;
Arrayprint(R, L, q);
}
From what I can tell, you understand at a low level that the address of the ith element of an array of T is base + sizeof(T) * i. That's correct, and it's good that you know that.
However, C and C++ handle this for you already. When you say q + i or q[i], it's actually compiling that into q + sizeof(T)*i anyway (with the latter also dereferencing the result).
So when you say q[sizeof(int)*i], that's actually compiling into *(q + sizeof(int)*sizeof(int)*i), which is clearly not what you wanted.
Thus, the index in the array you actually access is off by a factor of sizeof(int) and results in an out of bounds error, which is where your strange numbers are coming from.
I am using gcc compiler on ubuntu 16 , when I am printing value
garbage value is getting displayed
Instead of trying to fix what's broken in your raw array arimethics, consider using the standard containers:
#include <iostream>
#include <array>
constexpr size_t R = 3;
constexpr size_t L = 4;
using image_t = std::array<std::array<unsigned int, L>, R>;
void Arrayprint(const image_t& q) {
// range based for loops for convenience
for(auto& row : q) { // get references to each row
for(unsigned int colval : row) { // get the column values
std::cout << colval << "\t"; // print the values
}
std::cout << "\n";
}
}
int main() {
image_t image = {{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}};
Arrayprint(image);
}
Output:
1 2 3 4
5 6 7 8
9 10 11 12
I would like to convert an array of Integers
2, 3, 4, 8
5, 7, 9, 12
1, 0, 6, 10
to a string with the entries of that matrix appended in clockwise order
“2, 3, 4, 8, 12, 10, 6, 0, 1, 5, 7, 9”.
I have to keep declaration of int * Matrix and char * OutBuffer the way they are
int main()
{
int matrixArray[rowCount][columnCount] =
{ {2, 3, 4, 8},
{5, 7, 9, 12},
{1, 0, 6, 10}};
int * matrix;
string prebuffer;
char * outBuffer;
outBuffer = new (nothrow) char[24];
matrix = &matrixArray[0][0];
BuildStringFromMatrix(matrix, rowCount, columnCount, outBuffer);
}
I declare and address all my pointers before passing them in. However, I am not sure if I am going about allocating memory for the outBuffer to store the characters of prebuffer correctly?
void BuildStringFromMatrix(int* Matrix, int NumRows, int NumColumns, char * OutBuffer)
{
string prebuffer;
bool stringLeft = true;
int i = 0;
while (stringLeft)
{
int clockwiseDir[12] = { 1,1,1,4,1,1,0,4,-4,-1,-1,-1 };
prebuffer = to_string(Matrix[i]) + ", ";
OutBuffer = new char [prebuffer.length() + 1];
cout << prebuffer;
i += clockwiseDir[i];
if (i == 6)
{
prebuffer = to_string(Matrix[i]) + " ";
cout << prebuffer;
stringLeft = false;
}
}
}
**When I do not implement OutBuffer I have no trouble accessing and printing the matrix in clockwise format
But I how would I go about using OutBuffer to reference and print prebuffers contents??
I need numbers to display not unprintable symbols on the ASCII table
Thanks in advance :)
**
Firstly, in your loop under BuildStringFromMatrix function you are not using your i value anywhere.
Second, matrix = matrixArray should do fine.
I am trying to use Eigen:Map with Stride to map two matrices to an array. For example, if
arr = {1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 ,16 ,17 ,18 ,19 ,20 ,21 ,22 ,23 ,24}
I want the mapped matrices to be
mat1 = {1, 7, 13, 19;
3, 9, 15, 21;
5, 11, 17, 23}
and
mat2 = {2, 8, 14, 20;
4, 10, 16, 22;
6, 12, 18, 24}
The following code works:
int nmat = 2; // number of matrices
int nrow = 3; // number of rows for each matrix
int ncol = 4; // number of columns for each matrix
int arr_size = nmat*nrow*ncol; // size of the array.
int *arr = new int[arr_size];
Map<MatrixXi, 0, Stride<Dynamic, Dynamic> > mat1(arr ,nrow, ncol, Stride<Dynamic,Dynamic>(nrow*nmat, nmat));
Map<MatrixXi, 0, Stride<Dynamic, Dynamic> > mat2(arr+1 ,nrow, ncol, Stride<Dynamic,Dynamic>(nrow*nmat, nmat));
for (int i=0; i<arr_size; i++) {
arr[i] = i+1;
}
cout <<"mat1 = \n"<<mat1<<endl;
cout <<"mat2 = \n"<<mat2<<endl;
The results are:
mat1 =
1 7 13 19
3 9 15 21
5 11 17 23
mat2 =
2 8 14 20
4 10 16 22
6 12 18 24
However, I would like to declare and map the matrices separately like the following code:
MatrixXi mat1;
MatrixXi mat2;
new(&mat1) Map<MatrixXi, 0, Stride<Dynamic, Dynamic> > (arr ,nrow, ncol, Stride<Dynamic,Dynamic>(nrow*nmat, nmat));
new(&mat2) Map<MatrixXi, 0, Stride<Dynamic, Dynamic> > (arr+1 ,nrow, ncol, Stride<Dynamic,Dynamic>(nrow*nmat, nmat));
This will give me Segmentation fault.
If I comment out mat2 like the code below:
MatrixXi mat1;
// MatrixXi mat2;
new(&mat1) Map<MatrixXi, 0, Stride<Dynamic, Dynamic> > (arr ,nrow, ncol, Stride<Dynamic,Dynamic>(nrow*nmat, nmat));
// new(&mat2) Map<MatrixXi, 0, Stride<Dynamic, Dynamic> > (arr+1 ,nrow, ncol, Stride<Dynamic,Dynamic>(nrow*nmat, nmat));
Then there is no Segmentation fault, but the Stride is not working. The results are:
mat1 =
1 4 7 10
2 5 8 11
3 6 9 12
The reason I want to separate the declaration and initialization is that I want to write a class which mat1 and mat2 are members of it.
You mat1 and mat2 are of the type Map<MatrixXi, 0, Stride<Dynamic, Dynamic> >, but when you do it separately, you defined them as MatrixXi.
If you want them as a class member, you could follow the general way for an class member object.
class MyClass {
MyClass(int* arr, int nrow, int ncol, int nmat) :
a(3), v(10),
mat1(arr, nrow, ncol, Stride<Dynamic, Dynamic>(nrow * nmat, nmat)),
mat2(arr + 1, nrow, ncol, Stride<Dynamic, Dynamic>(nrow * nmat, nmat)) {
}
int a;
std::vector<int> v;
Map<MatrixXi, 0, Stride<Dynamic, Dynamic> > mat1;
Map<MatrixXi, 0, Stride<Dynamic, Dynamic> > mat2;
};
the new operator is not needed.
This question already has answers here:
Now that we have std::array what uses are left for C-style arrays?
(7 answers)
Closed 8 years ago.
array<int, 5> b = {12,45,12,4};
int B[5] = { 12, 45, 12, 4 };
for (auto item : b)
{
cout << item << endl; // 12,45,12,4, 0
}
cout << endl;
for (auto item : B)
{
cout << item << endl; // 12,45,12,4, 0
}
What is the difference between array<int,5> b; and int b[5];?
Template class std:;array is defined as a structure. It is an aggregate and has some methods as for example size().
The difference is for example that arrays have no assignment operator. You may not write
int b[5] = { 12, 45, 12, 4 };
int a[5];
a = b;
while structures have an implicitly defined assignment operator.
std::array<int, 5> b = { 12, 45, 12, 4 };
std::array<int, 5> a;
a = b;
Also using arrays you may not use initialization lists to assign an array. For example the compiler will issue an error for the following statement
int b[5];
b = { 12, 45, 12, 4, 0 };
However you can do these manipulations with std::array For example
std::array<int, 5> b;
b = { 12, 45, 12, 4, 0 };