Modifying the values of a 2d array of reference in a function - c++

This program must have a function that can accept 2 arrays and return their product in a third array. All of the arrays must be 2d, and a separate function must complete the multiplication of the elements memberwise. When I run this in visual studio I get the error:
Unhandled exception at 0x003f15ec in program4.exe: 0xC0000005:
Access violation reading location 0x00000000.
This could be due to my lack of knowledge about C++, but I think I may have made a syntax mistake or something.
Here is the program:
#include<iostream>
using namespace std;
void ProductArrays(int[3][4], int[3][4], int** array3[3][4]);
void main()
{
int array1[3][4] = { {1,3,5,7}, {9,11,13,15}, {17,19,21,23} };
int array2[3][4] = { {2,4,6,8}, {10,12,14,16}, {18,20,22,24} };
int** array3[3][4] = {0,0,0,0,0,0,0,0,0,0,0,0};
ProductArrays(array1, array2, array3);
system("pause");
return;
}
void ProductArrays(int array1[3][4], int array2[3][4], int** array3[3][4])
{
int i,j;
for (i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
**array3[i][j] = array1[i][j] * array2[i][j];
}
}
return;
}

I think what you mean for array3 to be a reference to a 2d array of pointers, but it's actually a 2d array of int**. So when you do the multiplication, this part:
**array3[i][j]
Is trying to dereference what's in array3[i][j], which is 0, hence the AccessViolation. I think you probably mean the signature to be:
void ProductArrays(int array1[3][4], int array2[3][4], int (&array3)[3][4])
And declare array3 to be of the same type as array1 and array2.

(1)
The declaration for array3 is wrong as you required.
int** array3[3][4] = {0,0,0,0,0,0,0,0,0,0,0,0};
You need this If I correctly understand you question:
int array3[3][4] = {0,0,0,0,0,0,0,0,0,0,0,0};
(3)
You are getting error because you were creating 2D array of pointers those are pointing to NULL (0) and you are assigning to 0 location.
**array3[i][j] = array1[i][j] * array2[i][j];
^ assign to `0` location
(2)
Declare you function like:
void ProductArrays(int array1[3][4], int array2[3][4], int (*array3)[4])
{ // ^ notice
int i,j;
for (i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
array3[i][j] = array1[i][j] * array2[i][j];
// ^ remove **
}
}
return;
}
call it from main like:
ProductArrays(array1, array2, array3);
Additional point, my answer is pass by address, and #Barry's answer is pass by reference. In C++ Both are allowed. (in C only pass by address is possible)
Pass by reference having power of pointers but simple to use like value variables So #Barry's answer is better. consider my answer for understanding points of view.

Related

Array initialization functions

I was playing around with C++ and I stumbled upon this problem. I'm trying to initialize an array pointer on the heap, and it works inside the initialize(), where it outputs 69, but in the main(), it crashes with the error EXC_BAD_ACCESS.
#include <iostream>
void initialize(int* array, int size) {
array = new int[size];
// Testing
array[2] = 69;
std::cout << array[2] << std::endl; // Works fine
}
int main() {
int size = 3;
int* array;
// Initializing
initialize(array, size);
// Testing
std::cout << array[2] << std::endl; // Crash, EXC_BAD_ACCESS
// Cleanup
delete[] array;
array = nullptr;
return EXIT_SUCCESS;
}
Please help me understand the problem with this.
Yes, I know I should use std::vector but I want to understand why this doesn't work :)
When you pass array to the function, a copy of that pointer is made. When you assign new int[size]; to array, you assign it actually to the argument, which is the copy I was talking about. To really modify the array defined in main, use references. Change the definition of the function to
void initialize(int*& array, int size)
or return the pointer like1
int* initialize(int size)
and try it again.
I recommend the second method due to its higher expressiveness: something like
initialize(array, 3);
does not make clear if array is modified or not. OTOH,
int* array = initialize(3);
does.
1 as noted by #Jack in the comments to this answer
The reason why the program fails is because you want the memory to be allocated outside the initialize function and the function to operate on that memory.
Simply remove the new statement from your function so that it looks like this...
void initialize(int* array, int size) {
for (int i = 0; i < size; i++) {
cout << array[i] << " ";
}
}
... then, do your allocation in main and just before the function call...
int size = 3;
int* array = new int [size];
initialize(array, size);
Pass the address of the pointer to avoid the error message

Method crashes every time I put the first integer into array. Bad operation?

I have a method which fills the array with integers:
void fill(int* a[], int dim1, int dim2)
{
int intinArray = 0;
for(int i=0;i<dim1;i++)
{
for(int j=0;j<dim2;j++)
{
cin >> intinArray;
a[i][j] = intinArray;
}
}
}
If I declare array in method main() like this:
int** tab;
fill(tab,3,3);
It crashes when I put the first integer in cin. Why? If there's a problem with this line:
a[i][j] = intinArray;
how should I change it?
The fundamental thing wrong with your code is that you declared pointers, but nowhere do you initialize the pointers to point somewhere. You treat the pointer as if it is a regular old 2 dimensional array of integer. So if it's as easy as that, why use pointers?
Given that this is a fundamental in pointer usage and you plainly aren't doing that, the solution is to review working code that uses pointer.
int main()
{
int *p; // uninitialized -- points to who-knows-where
*p = 10; // this is undefined behavior and may crash
}
Take that code and understand why it also may crash. That pointer points to "we don't know", and then you're assigning 10 to a location that is unknown to you, me, and everyone else reading this answer. See the problem? To fix it, you have to initialize the pointer to point somewhere valid, then you can dereference it and assign to it without error.
int main()
{
int *p; // uninitialized -- points to who-knows-where
int x = 20;
p = &x; // this is now ok, since p points to x
*p = 20; // now x changes to 20
}
Your problem is in this code
int** tab; // <- this one
fill(tab,3,3);
You declared a pointer, and are using it under the assumption that it is pointing to allocated memory. (I guess a source of confusion is that with C++ objects this isn't really the case)
A pointer is a pointer - it points to a location in memory. There's no guarantee that the value it points to is valid unless you explicitly make sure it is yourself.
Read PaulMcKenzie's answer for more about pointers.
Try
int tab[x][y] = {{0}};
fill(tab,3,3);
where x and y define your 2D array's width and height. You're going to have to handle bounds checking for your application.
Note that changing {{0}} to a non zero number will not initialize everything to that number.

Make array in cpp

I am trying to make a new array in my project
the code is:
#include <iostream>
using namespace std;
void makeArray( int *& arrayPtr, int size );
int main( )
{
int * arrPtr;
int size =10;
makeArray( arrPtr, size );
for(int j=0;j<size;j++)
{
cout<<arrPtr[j]<<endl;
}
}
void makeArray( int *& arrayPtr, int size )
{
int arr[size-1];
for(int i=0;i<size;i++)
{
arr[i]=0;
}
*&arrayPtr=*&arr;
}
According to the requirements i need to use the above "makeArray" method inorder to make the array.
When i run the code the output is garbage values not zero.....
any help will be appreciated
thank you
The way you are creating the array is on the stack, which means that it will not exist after the makeArray function finishes.
You will need to allocate the array on the heap.
So:
int arr[size-1];
should be:
int *arr = new int[size-1];
Also, I think you mean to do this in makeArray():
arrayPtr = arr;
Instead of:
*&arrayPtr=*&arr;
Which compiles but is more complex and is functionally the same thing in this context.
But you may prefer just returning an int* instead of taking a reference to the pointer.
Then when you are done using the array in main(), and set it to NULL just in case you accidentally use it again, like this:
for(int j=0;j<size;j++)
{
cout<<arrPtr[j]<<endl;
}
delete [] arrPtr;
arrPtr = NULL;
Why are you declaring a parameter as 'int *& arrayPtr'? Do you just need a pointer to an array? You should use 'int *arrayPtr' instead.
To answer your question, the problem is that you are declaring an array in the function makeArray's stack. Upon the completion of a function, that function's stack is destroyed, so you're passing the address of junk data. To avoid this, use dynamic memory allocation instead.
EDIT: Also, you should use memset instead of a for loop to zero an array. It's much faster.
The "arr" which you allocate in "makeArray()" is local. and when the functione is over the array is release. When you back to main you get garbage.
What you want to do, is to use the "new" operator to allocate this new array to be used in all program, unless you will free this memory by "delete".
so you can set your makeArray() to:
int* makeArray(int size )
{
int *arr = new[size];
for(int i=0;i<size;i++)
{
arr[i]=0;
}
return arr;
}
the in you main you need to initialize your arry by:
int * arrPtr = makeArray(10);
just don't forget to release this memory after you finsh:
delete[] arrPtr ;

using Pointers to a series of integers in C++

I am trying to make a c++ program with a class which holds integers on the "heap" and has only one method, pop() which returns the first item in the class and removes it. This is my code so far:
#include <iostream>
using namespace std;
class LinkList {
int *values; //pointer to integers stored in linklist
int number; // number of values stored in linklist
public:
LinkList(const int*, int); // Constructor (method declaration)
int pop(); // typically remove item from data structure (method declaration)
};
LinkList::LinkList(const int *v, int n){
number = n;
*values = *v;
int mypointer = 1;
while (mypointer<n) {
*(values+mypointer) = *(v+mypointer);
mypointer++;
}
}
int LinkList::pop() {
if (number>0) {
int returnme = *values; //get the first integer in the linklist
number--;
values++; //move values to next address
return returnme;
}
else {return -1;}
}
int main() {
int test[] = {1,2,3,4,5};
LinkList l1(test,5);
cout << l1.pop() << endl;
LinkList l2(test,5);
cout << l2.pop() << endl;
return 0;
}
The issue is that its failing at the line *values = *v, if i remove the 4th and 5th lines from the main method, I no longer get this issue, so its go to be a memory management thing.
What I want to do is to get values to point to a continuous bit of memory with integers in. I have tried to use arrays for this but keep just getting random memory addresses returned by pop()
Background: normal I programming in java, I've only be using C/C++ for 2 months, I'm using eclipse IDE in ubuntu, I can make very basic use of the debugger but currently I dont have functioning scroll bars in eclipse so I can't do somethings if they dont fit on my screen.
You are dereferencing an uninitialized pointer (values) at the line *values = *v; which is undefined behavior (UB). What this line says is "get the integer that values points to and assign to it the value pointed by v". The problem with this logic is that values doesn't yet point to anything. The result of this UB is the crash that you receive.
There are many other problems with this code, such as passing a const int* to the constructor with the intent of modifying those values. The biggest problem is that this is not an actual linked list.
*values = *v;
You dereference the values pointer in this line before initializing it. This is the source of the later errors, and the non-errors in the first three lines of main are simply due to luck. You have to allocate space via values = new int[n] and deallocate it in the destructor via delete[] values. std::vector does this work in a clean and exception-safe way for you.
Perhaps the problem is that you're incrementing an integer - mypointer, rather than a a pointer. If the integer requires more than one byte of space, then this might lead to errors. Could you try declaring a pointer and incrementing that instead?
The values member variable is a pointer to uninitialized memory. Before you start copying numbers into it you have to point it to valid memory. For example:
LinkList::LinkList(const int *v, int n){
number = n;
values = new int[n]; // allocate memory
int mypointer = 0;
while (mypointer<n) {
*(values+mypointer) = *(v+mypointer);
mypointer++;
}
}
LinkList::~LinkList() {
delete values; // release memory
}
Also, why do you call this a linked list while in fact you are using a memory array to store your numbers?

c++ pass auto matrix to function [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I use arrays in C++?
i have a problem.
i have to use auto darray(matrix).
const int size_m=10;
const int size_n=10;
void process(int *x)
{
//i can pass array, all is well, i work as with dynamic allocated array
for(int i=0;i<size_m;scanf("%d",&x[i]),i++);
}
void input_m(int **x)
/*
mistake is here,
a cause of my problem that i'm trying to work with matrix allocated in stack(auto matrix,local) as with dynamically allocated matrix.
i receive error like this : "cannot convert ‘int [100][100]’ to ‘int**’ in assignment" how should i pass it?
*/
{
for(int i=0;i<size_m;i++)
for(int j=0;j<size_n;j++)
scanf("%d",&x[i][j]);
}
int main()
{
int x[size_m];
input(x);
int matr_x[size_m][size_n];
input_m(matr_x);
return 0;
}
THANK YOU! it works.. it was so simple, as usual)
const int sizem=3;
const int sizen=3;
void _input(int x[sizem][sizen])
{
for(int i=0;i<sizem;i++)
for(int j=0;j<sizen;x[i][j]=1,j++);
}
int main()
{
int m=10,n=10;
int x[sizem][sizen]={{1,2,3},{5,7,4}};
_input(x);
for(int i=0;i<sizem;i++)
{ for(int j=0;j<sizen;printf(" %d",x[i][j]),j++);
puts("");
}
puts("");
return 0;
}
Your two-dimensional array is incompatible with the function you wrote for fundamental reasons of how memory works in C.
When you write int matrix[size_m][size_n] you are telling the compiler that you want a block of sizeof(int)*size_m*size_n bytes and you intend to store integers in it.
When you write int ** x you are telling the compiler that x is a pointer to a pointer to an integer. If you want to use x as a two-dimensional array, then x should point to not just one pointer, but the first pointer in an array of pointers, i.e. a contiguous region of memory that contains pointers for each row of your matrix. But you don't have any such array of pointers anywhere in the program you posted.
Since you know the dimensions of your matrix at compile time, you can fix this by changing the type of x be int x[size_m][size_n]. Better yet, make a typedef:
typedef int MyMatrix[size_m][size_n];
void input_m(MyMatrix x){ ... }
int main()
{
MyMatrix matr_x;
...
}
First of all, see the answer to this question. Your code should compile if you change void input_m(int **x) to void input_m(int x[size_m][size_n]) (assuming that both size_m and size_n are constants). Note that, as stated in the question that I linked to, "in general, to pass 2D arrays to functions you need to specify the array dimensions for all but the first dimension."