Why I can manipulate dynamic matrix without reference - c++

Let it be a create function for a dynamical allocated array:
void create(int *&a, int dim){
a=new int[dim];
for(int i=0;i<dim;i++){
a[i]=i+1;
}
Here, I need reference (&).
Now, I have a create function for a dynamical allocated matrix:
void create(int **&a,/* int**a, */ int lines,int rows){
...
}
I saw that reference is optional for dynamical allocated matrix create function. Why?

You need reference if you want to allocate the "outer" array - lines. Without it, you can allocate only "inner" arrays - rows (if "outer" array has been already allocated). So in your case, reference is mandatory.
void create(int **a, int lines, int rows)
{
a = new int*[lines]; // passed pointer to 'a' will point to an old address
for(int i = 0; i < lines; i++)
a[i] = new int[rows];
}

If you want to modify the pointer passed to a function inside the function, it needs to be passed by reference.
So no, the reference is not optional in your case. Wherever you saw that it's optional, was wrong.

My bad. I'm sorry.
I saw that refference in assignValues function isn't necessary so I thought that it is unnecessary for the create function, too.
Thank you all for replies.
Again, I'm sorry.
Here is my code:
#include <iostream>
#include <conio.h>
using namespace std;
void create(int **&a, int lines, int rows){
int i;
a = new int*[lines];
for (i = 0; i < lines; i++){
a[i] = new int[rows];
}
}
void assignValues(int **a, int lines, int rows){
int i,j,k = 1;
for (i = 0; i < lines; i++){
for (j = 0; j < rows; j++){
a[i][j] = k;
k++;
}
}
}
void print(int **a, int lines, int rows){
int i, j;
cout << "Matrix is: "<<endl;
for (i = 0; i < lines; i++){
for (j = 0; j < rows; j++){
printf("%3d",a[i][j]);
}
cout << endl;
}
}
int main()
{
int lines = 5;
int rows = 4;
int **a = 0;
create(a, lines, rows);
assignValues(a, lines, rows);
print(a, lines,rows);
_getch();
return 0;
}

Related

Function which copies an array of integers from one array to another using pointers in C++

The purpose of the Copy function in the following code is to copy an array of integers from one array to another using C++ but the output seems wrong.
What could be the problem here?
#include <iostream>
using namespace std;
void Copy(int old_array[],int new_array[],int length)
{
int *ptr1 = old_array;
int *ptr2 = new_array;
int i = 0;
for(int i=0 ; i<length ; i++)
{
*(ptr2++) = *(ptr1++);
}
for (int i = 0; i <2; i++)
{
cout<<*(ptr2 + i)<<endl;
}
}
int main()
{
int a[2]={0,1};
int b[2];
Copy(a,b,2);
}
This is the output:
ptr2 is one past the end of the array when your print loop runs.
Try this:
void Copy(int old_array[], int new_array[], int length)
{
int* ptr1 = old_array;
int* ptr2 = new_array;
int i = 0;
for (int i = 0; i < length; i++)
{
*(ptr2++) = *(ptr1++);
}
ptr2 = new_array;
for (int i = 0; i < 2; i++)
{
cout << *(ptr2 + i) << endl;
}
}
Your ptr2 is pointing to the element b[2] (which is out-of-bound access) at the time you are printing it in the second for loop.
You can fix it by subtracting the length from the ptr2 in the second for loop like below.
#include <iostream>
using namespace std;
void Copy(int old_array[],int new_array[],int length)
{
int *ptr1 = old_array;
int *ptr2 = new_array;
int i = 0;
for(int i=0 ; i<length ; i++)
{
*(ptr2++) = *(ptr1++);
}
for (int i = 0; i <2; i++)
{
cout<<*(ptr2 + i - length)<<endl;
}
}
int main()
{
int a[2]={0,1};
int b[2];
Copy(a,b,2);
}
The copy seems fine but the second for is accessing ptr2 which was incremented in the first for and is point to some invalid memory position. You could use new_array in this second loop.
I suppose this second loop is only for debug and will be better located in the main using, in you case, the variable b.

Cannot pass 2d array into a helper function in c++

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.

Extract pair numbers from array

Good evening, folks.
I'm currently experiencing difficulties with extracting pair numbers from an array. I have the following code:
#include <iostream>
using namespace std;
int *paire(int *d, int length) {
int counter = 0;
int position = 0;
for (int i=0; i<length; i++) {
if (d[i] % 2 ==0)
counter++;
}
int *k = new int[counter];
for (int i=0; i<length; i++) {
if (d[i] % 2 ==0) {
k[position] = d[i];
position++;
}
}
return k;
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int *array1 = paire(b,8);
for (int i=0; i<5; i++) { // how can I point here to the counter in paire() ?
cout<<array1[i];
}
delete[] array1;
return 0;
}
So I think I've got it right with initializing the new array in function paire, but I'm having difficulties to iterate through the array.
P.S. I'm first year in university, so I would really be thankful if you can keep the same simplicity in the answers. Thanks in advance!
It appears that you need to return 2 separate values: the number of even numbers in the array b, and the address of the newly allocated memory that is storing exclusively those even numbers.
Since you can not return multiple variables, one solution that does minimal modification to your code would be as follows.
int *paire(int *d, int length, int& counter) {
counter = 0;
// rest of your function remains unchanged
// ...
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int evenNumbers;
int *array1 = paire(b,8, evenNumbers);
for (int i=0; i<evenNumbers; i++) {
cout<<array1[i];
}
delete [] array1;
return 0;
}
Alternatively, you can return the value in counter and send the reference to the int* variable as an argument to paire function. Or, you can declare paire to have return type void and use references to pass back both the values.
You can further simplify your function by allocating to that of the length and returning the counter by an output parameter.
#include <iostream>
using namespace std;
int *paire(int *d, int length, int &counter) {
counter = 0;
int *k = new int[length]; // allocate for the maximum memory
for (int i = 0; i < length; ++i) {
if (d[i] % 2 == 0) {
k[counter++] = d[i];
}
}
return k;
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int counter = 0;
int *array1 = paire(b,8, counter);
for (int i=0; i<counter; i++) { // how can I point here to the counter in paire() ?
cout<<array1[i] << " ";
}
delete [] array1;
return 0;
}
But please note that as others have already pointed out this method is quite error prone in the sense that it leaves the responsibility to the client to delete the internal memory used by paire function.

C++ Merging 2 sorted arrays into 1 sorted

So I am trying so merge 2 sorted arrays into one and I get really weird numbers like an output. Here is my code:
#include<iostream>
using namespace std;
int* add(int first[],int second[], int sizeFirst, int sizeSecond)
{
int result[sizeFirst + sizeSecond];
int indexFirst = 0,indexSecond = 0;
for(int i = 0;i < sizeFirst + sizeSecond;i++)
{
if(indexFirst == sizeFirst || first[indexFirst] > second[indexSecond])
{
result[i] = second[indexSecond];
indexSecond++;
}
else
{
result[i] = first[indexFirst];
indexFirst++;
}
}
return result;
}
int main()
{
int n;
cin>>n;
int arr[n];
for(int i = 0;i < n;i ++)
cin>>arr[i];
int m;
cin>>m;
int arr2[m];
for(int i = 0;i < m;i ++)
cin>>arr2[i];
int *res;
res = add(arr,arr2,n,m);
for(int i = 0;i < n + m;i ++)
cout<<res[i]<<" ";
return 0;
}
Notes: It sorts it properly, so the mistake is not there. Also I need to do it as a function because I will need it later on for some other stuff.
return result;
You are returning a pointer to local array, which gets destroyed immediately after - this is undefined behavior. You should either allocate it using new or use std::vector (which is preferred).
Also, int result[sizeFirst + sizeSecond]; is not valid C++ because the standard doesn't allow variable sized arrays (but int* result = new int[sizeFirst + sizeSecond]; is valid).

c++ function that fills array

What I'm trying to do:
User inputs two numbers.
Array is declared using those numbers as dimensions.
Function outside main() is filling the array.
Array is accessed in main() for further thingies.
What I have problem with:
Function + array combination doesn't seem to work as I think.
What I did:
void tablica1(int h, int w)
{
int m,n;
for(m=0; m<h; m++)
for(n=0; n<w; n++)
{
arr[h][w]=1;
}
}
What happens:
array arr is inaccessible in tablica1() because it has not been declared in that function.
Of course, when I declare the array in tablica1() it becomes inaccessible in main().
Possible solutions:
Passing arr to tablica1() as a reference - no idea how to do that
Declaring arr in tablica1() and somehow passing it to main() - no idea how to do that
Other possible solutions?
You can declare the array outside of both, at compilation unit level:
int arr[10][10];
void func() {
for (int i=0; i<10; i++) {
for (int j=0; j<10; j++) {
arr[i][j] = i + j;
}
}
}
int main(int argc, const char *argv[]) {
func();
std::cout << arr[3][4] << "\n"; // Output will be 7
return 0;
}
If you want handle a dynamically-sized matrix the most common pattern is to use an std::vector of std::vectors (it's a little more general and therefore a little less efficient than a 2d matrix because each row can have a different length, but in most cases the cost difference is not a big issue)
#include <vector>
std::vector< std::vector< int > > arr;
void func() {
int height = arr.size();
int width = arr[0].size();
for (int i=0; i<height; i++) {
for (int j=0; j<width; j++) {
arr[i][j] = i + j;
}
}
}
int main() {
int height = 13;
int width = 7;
arr = std::vector< std::vector<int> >(height, std::vector<int>(width));
func();
...
}
the two solutions you mentioned
1、Passing arr to tablica1() as a reference
void tablica1(int h, int w,int **arr)
{
int m,n;
for(m=0; m<h; m++)
for(n=0; n<w; n++)
{
arr[h][w]=1;
}
}
void main()
{
const int h=100,w=100;
int arr[h][w];
tablica1(h,w,arr);
}
2、Declaring arr in tablica1() and somehow passing it to main()
int **tablica1(int h, int w)
{
int m,n;
int **arr=new int*[h];
for(int i=0;i<h;i++)
{
arr[i]=new int[w];
}
//it is best to initialize arr by setting each element 0
for(m=0; m<h; m++)
for(n=0; n<w; n++)
{
arr[h][w]=1;
}
return arr;
}
void main()
{
const int h=100,w=100;
int **arr=tablica1(h,w);
//do somting
//delete arr
for(int i=0;i<h;i++)
{
delete []arr[i];
}
delete []arr;
}
If you want to declare a dynamic multidimensional array you can do that with the template give below.
#include<iostream.
#include <vector>
using namespace std;
typedef vector<int> vi;
vector<vi> arr; // arr is a dynamic two dimensional array.
vi.assign(10,vi());//10 rows of type vi .
If you want to enter values in arr you can do that by
vi[0].push_back(a);
vi[0].push_back(b); // a,b,c are some example values..
vi[1].push_back(c);
You can understand using this code
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
typedef vector <int> vi;
vector<vi> arr;// dynamic multidimensional array
int main(){
cout<<"enter array size\n";
int h,w,temp;;
cin>>h>>w;
arr.assign(h,vi());
int i, j;
for(i=0; i < h ;i++)
for(j=0; j < w; j++)
{
cin>>temp;
arr[i].push_back(temp);
}
// for printing
for(i=0; i < h ;i++){
for(j=0; j < w; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
return 0;
}