This question already has answers here:
Passing a 2D array to a C++ function
(17 answers)
Closed 2 years ago.
I'm a beginner in C++
I been trying to make a function that prints out all the elements within a 2D array, but I can't get this work, and I need some help.
It appears to me that my printArray function can't take 2D array as a valid input data.
Can anyone throw me an advice? Also, would there be a better way to build a multidimensional string array without using std::string?
Thanks for your help!
int main ()
{
std::string faces[5] = { "Pig", "sex", "John", "Marie", "Errol"};
printArray(faces);
std::string TwoD[2][2] = {{ "Aces", "Deuces"}, { "Hearts", "Diamonds"}};
//print2DArray(TwoD);
std::cin.get();
}
void print2DArray(std::string x[])
{
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
{
std::cout << x[i][j] << std::endl;
}
}
You have to use proper type (matched with data to be passed) for function arguments.
Also you have to declare or define functions before using them.
#include <iostream>
#include <string>
void print2DArray(std::string x[][2]); // declare function
int main ()
{
std::string TwoD[2][2] = {{ "Aces", "Deuces"}, { "Hearts", "Diamonds"}};
print2DArray(TwoD);
}
void print2DArray(std::string x[][2])
{
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
{
std::cout << x[i][j] << std::endl;
}
}
Using const char* may be a good way to build a multidimensional string array without using std::string if you are not going to modify the strings.
#include <iostream>
void print2DArray(const char* x[][2]); // declare function
int main ()
{
const char* TwoD[2][2] = {{ "Aces", "Deuces"}, { "Hearts", "Diamonds"}};
print2DArray(TwoD);
}
void print2DArray(const char* x[][2])
{
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
{
std::cout << x[i][j] << std::endl;
}
}
Related
I was learning c++ and implementing the game of life when I created a helper function to print the current board which is a 2d array. I cannot seem to pass the array into the function as I get an error, "Candidate function not viable: no known conversion from 'char [rows][cols]' to 'char (*)[cols]' for 3rd argument." I am using Xcode as an ide if that helps.
void printArray(int rows, int cols, char board[rows][cols]){
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols; c++){
cout << board[r][c];
cout << " ";
}
cout << "\n";
}
}
int main(){
char board[5][5];
for(int r = 0; r < 5; r++){
for(int c = 0; c < 5; c++){
board[r][c] = 0;
}
}
printArray(5, 5, board);
return 0;
}
I've tried switching up the parameter to different things such as char **board, char board[][cols], char (*board)[cols]. Even casting my input board which leads to other errors.
If you want to pass 2d arrays to a function there is a special syntax. Unfortunately, the other previous 2 answers do not answer fully correctly.
You can pass by reference or by pointer. The array dimensions must be compile time constants. That is a requirement from C++.
Please see:
constexpr size_t NumberOfRows = 3;
constexpr size_t NumberOfColumns = 4;
// Typedef for easier usage
using IntMatrix2d = int[NumberOfRows][NumberOfColumns];
//Solution 1 ------
// Pass by reference
void function1(int(&matrix)[NumberOfRows][NumberOfColumns]) {}
// Pass by pointer
void function2(int(*m)[NumberOfRows][NumberOfColumns]) {}
//Solution 2 ------
// Pass by reference
void function3(IntMatrix2d& matrix) {}
// Pass by pointer
void function4(IntMatrix2d* matrix) {}
int main()
{
// Solution 1
// Handwritten matrix. Dimension is compile time constant
int matrix1[NumberOfRows][NumberOfColumns];
// Pass by reference
function1(matrix1);
// Pass by pointer
function2(&matrix1);
// Solution 2 -----
IntMatrix2d matrix2;
// Pass by reference
function3(matrix2);
// Pass by pointer
function4(&matrix2);
return 0;
}
If you typedef or use using for your type definition, then it gets rather intuitive.
If you are not very comfortable with pointers then there are some easy ways to do the task
1. You have to define the 2d array size by default, before passing array to the function so that the size doesn't seem to be unknown to the function.
#include <iostream>
const std::size_t rows=5;
const std::size_t cols=5;
void printArray(char board[rows][cols]) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
std::cout << board[r][c];
std::cout << " ";
}
std::cout << "\n";
}
}
int main() {
char board[rows][cols];
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
board[r][c] = '0';
}
}
printArray(board);
return 0;
}
2. Use vector. Make your board a vector.
#include <iostream>
#include <vector>
void printArray(std::vector<std::vector<char>> &board) {
for (int r = 0; r < board.size(); r++) {
for (int c = 0; c < board[0].size(); c++) {
std::cout << board[r][c];
std::cout << " ";
}
std::cout << "\n";
}
}
int main() {
std::vector<std::vector<char>> board(rows, std::vector<char>(cols, '0'));
printArray(board);
}
I encountered this problem while doing a project for a class. To work around it, I made a double pointer array, and then used passed it to the function to manipulate it.
int** createArr(){
int** pixels = 0;
pixels = new int*[numrows];
for (int row = 0; row < numrows; row++){
pixels[row] = new int[numcols];
for (int col = 0; col < numcols; col++){
ss >> pixels[row][col];
}
}
return pixels;
}
int** newArr = createArr(); //calls function to create array
func(newArr); //where func is a function that modifies the array.
Don't forget to delete your arrays at the end to avoid memory leaks. Hope this helps.
could you help me with little problem?
I have following class;
class Link
{
private:
Demand *demand_[NUMBER_OF_CORES][NUMBER_OF_SLICES];
public:
Link()
{
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
demand_[i][j] = NULL;
}
}
}
int virtualPut();
}
There will be problem with demand_ array. In the constructor everything is fine, after initialization I can use if (demand_[i][j] == NULL).
Problem starts in virtualPut()
int Link::virtualPut()
{
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
std::cout << "We're in " << i << " " << j << " \n" << std::flush;
if (demand_[i][j] == NULL) //SEGMENTATION FAULT
{
std::cout << "EMPTY\n";
}
}
}
}
And also - if I call virtualPut() in constructor (just for test) it works fine.
But outside Link class I use.
void someFunction(Link *tab, int links)
{
tab = new Link[links];
tab[0].virtualPut(); //also just for test
}
What could be a problem here? I know that I can use vector, but that won't help me understand this memory problem.
One more thing - Dr. Memory says:
UNADDRESSABLE ACCESS: reading 0x0000000000000009-0x0000000000000011 8 byte(s)
But why?
EDIT!
Problem solved in comments, thank you
The code you show us is okay. I ran it on my side with huge values, and there is no Segfault.
You declared a "Demand* array of array" in your Link class, and this is a valid declaration, the memory should be allocated.
What I do suspect is that NUMBER_OF_CORES and/or NUMBER_OF_SLICES doesn't have the same value in the code where you defines the Link class and in the code where you defined the virtualPut method.
Something like :
#define NUMBER_OF_CORES 10
#define NUMBER_OF_SLICES 10
class Link
{
private:
Demand *demand_[NUMBER_OF_CORES][NUMBER_OF_SLICES];
...
}
and
#define NUMBER_OF_CORES 5000
#define NUMBER_OF_SLICES 5000
int Link::virtualPut()
{
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
// here you will have buffer overflow
...
}
What I would do :
use std::vector
probably use a single entry array, and wrap it up
don't use #define, it's messy
don't use arrays, it generates buffer overflow
That would be something like this :
class Link
{
private:
std::vector<Demand*> demand_;
const int NUMBER_OF_CORES = 10;
const int NUMBER_OF_SLICES = 50;
private:
int getIdx(int i, int j)
{
return i*NUMBER_OF_SLICES + j;
}
public:
Link()
{
demand_.resize(NUMBER_OF_CORES * NUMBER_OF_SLICES);
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
demand_[getIdx(i,j)] = NULL;
}
}
}
int virtualPut();
};
Note : additionaly, you showed us a virtualPut() that should return an int but doesn't.
I want to declare two dimensional array with variable size.
I wrote the following code but something goes wrong!
int **p2DArray;
p2DArray = new int*[target_counter_new];
for (int i = 0; i < target_counter_new; ++i)
{
p2DArray[i] = new int[target_counter_old];
}
for(int i_oghli=0;i_oghli<target_counter_new;i_oghli++)
for(int j_oghli=0;j_oghli<target_counter_old;j_oghli++)
{
p2DArray[i_oghli][j_oghli]=i_oghli+10;
cout<<p2DArray[i_oghli][j_oghli];
}
what is problem here ?
#include <iostream>
using namespace std;
const int target_counter_new = 4;
const int target_counter_old = 4;
int main() {
int **p2DArray;
p2DArray = new int*[target_counter_new];
for (int i = 0; i < target_counter_new; ++i) {
p2DArray[i] = new int[target_counter_old];
}
for(int i_oghli=0;i_oghli<target_counter_new;i_oghli++) {
for(int j_oghli=0;j_oghli<target_counter_old;j_oghli++) {
p2DArray[i_oghli][j_oghli]=i_oghli+10;
cout<<p2DArray[i_oghli][j_oghli] << " ";
}
cout << endl;
}
// don't forget to delete the array
for (int i = 0 ; i < target_counter_new; ++i) {
delete [] p2DArray[i];
}
delete [] p2DArray;
return 0;
}
Check here : code
There doesn't appear to be any problem.
This is probably so simple, but I can't figure out why this won't compile.
void display(int);
const int rows = 2;
const int cols = 2;
int main()
{
int ray[rows][cols] = {{1,2 },
{3,4}};
display(ray);
return 0;
}
void display(const int ray[][cols]){
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
cout << ray[i][j] << endl;
}
}
}
invalid conversion from ‘int (*)[2]’ to ‘int’ [-fpermissive]|
This code will work
const int rows = 2;
const int cols = 2;
void display( const int ray[][cols]);
int main()
{
int ray[rows][cols] = {{1,2 },
{3,4}};
display(ray);
return 0;
}
void display( const int ray[][cols]){
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
cout << ray[i][j] << endl;
}
}
}
Your function definition and function declaration do not match, one of them is of type int while the other is type void
Your function declaration is
void display(int);
and the definition is
int display(const int ray[0][cols])
and
int display(const int ray[0][cols])
^
0 ?
I think I see the problem here
The prototype is wrong. If you want a 2D array arg, it's more like this
int display(const int ray**);
The forward declaration of display is wrong. Either fix forward declaration or change order of functions:
#include <iostream>
using namespace std;
const int rows = 2;
const int cols = 2;
int display(const int ray[0][cols]){
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
cout << ray[i][j] << endl;
}
}
}
int main()
{
int ray[rows][cols] = {{1,2 },
{3,4}};
display(ray);
return 0;
}
Live Example
Since you use global variables anyway, the easy thing is to change your declaration of display:
Declare display like this:
void display(int** array)
{...}
In this case you will actually be able to send your 2D array to the function because the type will match. A 2D array is an array of arrays and an array is just a pointer associated with some memory.
I am not giving the appropriate answer to this question. But an alternative.
As C++ suggests to use std::string inplace of char* . It also suggests to use vectors instead of array wherever applicable.
#include <iostream>
#include <vector>
void display( std::vector<std::vector<int>> );
int main()
{
std::vector<std::vector<int>> int_vec{ { 1 , 2 } , { 3 , 4 } };
display( int_vec );
system("PAUSE");
return EXIT_SUCCESS;
}
void display( std::vector<std::vector<int>> integer_vector )
{
for( auto& i : integer_vector )
{
for( auto& j : i )
{
std::cout << j << std::endl;
}
}
}
The global variables as rows and cols are gone :).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I use arrays in C++?
I was having trouble copying an array to an array. I have a feeling it may be because of the use of pointers but correct me if I'm wrong.
My function is the following:
bool sodoku::rowTest(sodoku *arr[9][9])
{
int row = 0;
while(row < 9)
{
for(int j = 0; j < 9; j++)
{
for(int k = 0; k < 9; k++)
{
if(arr[row][j]->number == arr[row][j]->possibleNumbers[k])
{
for(int i = 0; i < 9; i++)
{
arr[row][i]->possibleNumbers[k] = 0;
}
}
for(int g = 0; g < 7; g++)
{
int t = 8;
arr[row][g]->possibleNumbers[k] = arr[row][t]->possibleNumbers[k];
}
cout << "arr row j num : " << arr[row][j]->possibleNumbers[k] << "row: " << row << " column: " << j << endl;
}
}
row++;
}
if(row == 9)
return true;
}
return true;
}
My little section of trouble is here:
for(int g = 0; g < 7; g++)
{
arr[row][g]->possibleNumbers[k] = arr[row][8]->possibleNumbers[k];
}
For some reason when I cout each element, the copying doesn't occur. Could anyone help me as to know why this would hhappen? I just want every array from arr[row][1]->possibleNumbers[k] to arr[row][7]->possibleNumbers[k] have the same values as arr[row][8]->possibleNumbers[k]. PossibleNumbers ranges from 0 to 9, if that helps.
If anyone could help that'd be great.
Thanks.
Array variables are not copied, but you can use std::copy.
Also, passing arrays by value leads to array decay, which means that a lvalue of T(&)[N] actually gets passed as T*. To prevent this, pass by reference instead.
Here is a generic helper function that does this for you:
#include <algorithm>
template <typename T, int N>
void copy(T(&dest)[N], T(&src)[N])
{
std::copy(dest, dest+N, src);
}
Now you can just say
char dest[5];
char src [5];
copy(dest, src); // provided same element type and size
Note also, that member arrays are copied
struct SudokuRow
{
unsigned char cells[9];
};
SudokuRow a, b;
a = b; // copies just fine