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
Related
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;
}
}
so I am having a little bit of trouble getting this program to work without it throwing the errors:
"request for member 'insertArray' in 'arr', which is of non-class type 'int [10]' " and
"request for member 'print' in 'arr', which is of non-class type 'int [10]' ".
Both of those errors have to do with using my functions with an array, you can see the code below:
#include <iostream>
using namespace std;
int size = 0;
int *arr;
void insertArray(int val)
{
int i = 0;
while (i < size && arr[i] < val)
i++;
for (int k = size - 1; k >= i; k--)
{
arr[k + 1] = arr[k];
}
arr[i] = val;
size++;
}
void print()
{
cout << "The array is: ";
for (int j = 0; j < size; j++)
{
cout << arr[j];
}
}
int main()
{
int arr[10];
cout << "Please enter 5 values: \n";
for (int i = 0; i < 5; i++)
{
int num = 0;
cin >> num;
arr.insertArray(num); // Error 1: vs code error squiggles say: "expression must have class type"
arr.print(); // Error 2: vs code error squiggles say: "expression must have class type"
}
return 0;
}
I don't know how to fix the errors or what they mean either.
Thanks for the help in advance folks!
arr is just a plain-old C array, you can't define new functions on it. You need to define a class or struct if you want to do that.
What you have here is procedural code, so you're constrained by that model and must pass in arr as an argument.
I've tried to wrangle your original code into this form with as few modifications as necessary:
#include <iostream>
void printArr(const int* arr, const size_t size)
{
std::cout << "The array is: ";
for (int j = 0; j < size; j++) {
std::cout << arr[j];
}
std::cout << std::endl;
}
int main()
{
const size_t count = 5;
int arr[count];
std::cout << "Please enter 5 values: \n";
for (int i = 0; i < 5; i++)
{
std::cin >> arr[i];
}
printArr(arr, count);
return 0;
}
The whole insertArray function was just too confusing so I deleted it presuming what you were trying to do was add things at the end of the array anyway.
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 have a 2D array and I want to define a function that returns the value of the index that the user gives me using operator overloading.
In other words:
void MyMatrix::ReturnValue()
{
int row = 0, col = 0;
cout << "Return Value From the last Matrix" << endl;
cout << "----------------------------------" << endl;
cout << "Please Enter the index: [" << row << "][" << col << "] =" << ((*this).matrix)[row][col] << endl;
}
The operation ((*this).matrix)[row][col] should return an int.
I have no idea how to build the operator [][].
Alternatively, I could concatenate a couple of calls to the operator [], but I didn't succeed in it, because the first call to that operaror will return int* and the second one will return int, and it compel to build another operator, and I dont want to do that.
The data matrix is defined like
int** matrix; matrix = new int*[row];
if (matrix == NULL)
{
cout << "Allocation memory - Failed";
}
for (int i = 0; i < row; i++)//Allocation memory
{
matrix[i] = new int[col];
if (matrix[i] == NULL)
{
cout << "Allocation memory - Failed";
return;
}
}
What can I do?
Thank you,
Simply, such an operator does not exist, so you can not overload it.
A possible solution is to define two classes: the Matrix and the Row.
You can define the operator[] of a Matrix so that it returns a Row, then define the same operator for the Row so that it returns an actual value (int or whatever you want, your Matrix could be also a template).
This way, the statement myMatrix[row][col] will be legal and meaningful.
The same can be done in order to assign a new Row to a Matrix or to change a value in a Row.
* EDIT *
As suggested in the comments, also you should take in consideration to use operator() instead of operator[] for such a case.
This way, there wouldn't be anymore the need for a Row class too.
You can define your own operator [] for the class. A straightforward approach can look the following way
#include <iostream>
#include <iomanip>
struct A
{
enum { Rows = 3, Cols = 4 };
int matrix[Rows][Cols];
int ( & operator []( size_t i ) )[Cols]
{
return matrix[i];
}
};
int main()
{
A a;
for ( size_t i = 0; i < a.Rows; i++ )
{
for ( size_t j = 0; j < a.Cols; j++ ) a[i][j] = a.Cols * i + j;
}
for ( size_t i = 0; i < a.Rows; i++ )
{
for ( size_t j = 0; j < a.Cols; j++ ) std::cout << std::setw( 2 ) << a[i][j] << ' ';
std::cout << std::endl;
}
}
The program output is
0 1 2 3
4 5 6 7
8 9 10 11
I have no idea how to build the operator [][].
Sometimes it is fine to use a different operator, namely ():
int& Matrix::operator () (int x, int y)
{
return matrix[x][y];
}
const int& Matrix::operator () (int x, int y) const
{
return matrix[x][y];
}
int diagonal (const Matrix& m, int x)
{
return m (x, x); // Usage.
}
Advantage:
No need to use "intermediate" class like Row or Column.
Better control than with Row& Matrix operator (int); where someone could use the Row reference to drop in a row of, say, illegal length. If Matrix should represent a rectangular thing (image, matrix in Algebra) that's a potential source of error.
Might be less tedious in higher dimensions, because operator[] needs classes for all lower dimensions.
Disadvantage:
Uncommon, different syntax.
No more easy replacement of complete rows / columns, if that's desired. However, replacing columns is not easy, anyway, provided you used rows to model (and vice versa).
In either case, there are pros and cons if the number of dimensions are not known at runtime.
I was looking for self-tested array replacement...
Improved version returns reference or NULL reference and checks boundaries inside.
#include <iostream>
#include <iomanip>
template<typename T, int cols>
class Arr1
{
public:
Arr1(T (&place)[cols]) : me(place) {};
const size_t &Cols = cols;
T &operator [](size_t i)
{
if (i < cols && this != NULL) return me[i];
else {
printf("Out of bounds !\n");
T *crash = NULL;
return *crash;
}
}
private:
T (&me)[cols];
};
template<typename T, int rows, int cols>
class Arr2
{
public:
const size_t &Rows = rows;
const size_t &Cols = cols;
Arr2() {
ret = NULL;
for (size_t i = 0; i < rows; i++) // demo - fill member array
{
for (size_t j = 0; j < cols; j++) matrix[i][j] = cols * i + j;
}
}
~Arr2() {
if (ret) delete ret;
}
Arr1<T, cols>(&operator [](size_t i))
{
if (ret != NULL) delete ret;
if (i < rows) {
ret = new Arr1<T, cols>(matrix[i]);
return *ret;
}
else {
ret = NULL;
printf("Out of bounds !\n");
return *ret;
}
}
//T(&MemberCheck)[rows][cols] = matrix;
private:
T matrix[rows][cols];
Arr1<T, cols> *ret;
};
template<typename T,int rows, int cols>
class Arr
{
public:
const size_t &Rows = rows;
const size_t &Cols = cols;
T(&operator [](size_t i))[cols]
{
if (i < rows) return matrix[i];
else {
printf("Out of bounds !\n");
T(*crash)[cols] = NULL;
return *crash;
}
}
T (&MemberCheck)[rows][cols] = matrix;
private:
T matrix[rows][cols];
};
void main2()
{
std::cout << "Single object version:" << endl;
Arr<int, 3, 4> a;
for (size_t i = 0; i <= a.Rows; i++)
{
int *x = &a[i][0];
if (!x) printf("Fill loop - %i out of bounds...\n", i);
else for (size_t j = 0; j < a.Cols; j++) a[i][j] = a.Cols * i + j;
}
for (size_t i = 0; i < a.Rows; i++)
{
for (size_t j = 0; j <= a.Cols; j++) {
std::cout << std::setw(2) << a[i][j] << ' ';
if (a.MemberCheck[i][j] != a[i][j])
printf("Internal error !");
}
std::cout << std::endl;
}
std::cout << endl << "Double object version:" << endl;
Arr2<int, 3, 4> a2;
for (size_t i = 0; i < a2.Rows; i++)
{
for (size_t j = 0; j <= a2.Cols; j++) {
int &x = a2[i][j];
if (&x)
{
x++;
std::cout << std::setw(2) << a2[i][j] << ' ';
//if (&a2.MemberCheck[i][j] != &a2[i][j])
// printf("Internal error !");
}
}
}
}
Output
Single object version:
Out of bounds !
Fill loop - 3 out of bounds...
0 1 2 3 4
4 5 6 7 8
8 9 10 11 -858993460
Double object version:
1 2 3 4 Out of bounds !
5 6 7 8 Out of bounds !
9 10 11 12 Out of bounds !
it works fine in the program below
#include<iostream>
using namespace std;
class A{
public:
int r,c;
int** val;
A()
{
r=0;c=0;val=NULL;
}
A(int row,int col)
{
r=row;c=col;
int count=0;
val=new int*[row];
for(int i=0;i<r;i++){
val[i]=new int[col];
for(int j=0;j<c;j++){
count++;
val[i][j]=count;
}
}
}
int* &operator[](int index){
return val[index];
}
};
int main(void){
A a(3,3);
cout<<a[1][2];
return 0;
}
here, a[1][2] first computes a[1]-->which returns 2nd row as (int*) type
then it's read as (int*)[2] which returns 3rd element of that row.In short,
a[1][2]------>(a[1])[2]------>(val[1])[2]------>val[1][2].