Im getting a runtime error of exc_bad_access ( code = 1, address=0x0) on line
asize = **y[0] + **y[1];
in the summation function.
I know the problem is not a memory leak, so i don't quite know how to go about solving this problem.
void allocArr (int **&x, int ***&y, int **&q, int ****&z)
{
x = new int *[2];
y = new int **(&*x);
q = &*x;
z = new int ***(&q);
}
void summation(int ***&y, int arr[])
{
int asize = 0;
asize = **y[0] + **y[1];
**y[2] = *new int [asize];
*(arr + 2) = asize;
}
void putArr(int **&x, const int &size1,const int &size2)
{
x[0] = *new int* [size1];
x[1] = *new int* [size2];
}
int main()
{
int size1, size2;
int a = 1, b = 2;
int** x;
int*** y;
int** q;
int**** z;
int arr[2];
allocArr(x, y, q, z);
Input(x, arr, size1, size2, a, b);
summation(y, arr);
display(z);
}
Thank you for the help.
Three things.
1.)The function arguments for y are int *& . Did you overload int with a bracket operator somewhere else? As specified, the int pointer should not have a [].
2.) Bracket operators are higher in precedence than a dereference operator. (Almost always a good idea to enclose them within parenthesis). The way this is written, the bracket operator will be performed before the deref.
3.) It seems unusual that you should need so many dereference operators. Are they really necessary?
Related
Please take a look at the code below:
#include <iostream>
using namespace std;
int main(){
char matrix[2][2][2];
return 0;
}
int getMatrixData(char matrix[][2][2], int x, int y, int z) {
return matrix[x][y][z];
}
When matrix 3d array passed in as a parameter into a function, why is it ok not to specify the first [] size? How this missing dimension can be explained?
Your code is syntactically incorrect. Assuming you meant int getMatrixData(char matrix[][2][2], int x, int y, int z).
When you pass array arguments to function, array decays to pointer to first element (type char [2][2] in this case).
Now some syntax of array and pointer are similar so you don't find much difference.
When multidimensional array is passed, for example 3d in your case, it can be seen as array of 2-d arrays. So you need to give the type of each element char [2][2] in your case and you can skip the dimension of final array as it will decay to pointer anyway. char [2][2] is the information compiler needs to compute the offset of each element.
offset of matrix[x][y][z] = base address of matrix +
x * sizeof(char [2][2]) +
y * sizeof(char [2]) +
z
If you don't pass the dimensions of initial element, compiler can't resolve sizeof in above equation. Passing skipped dimension is optional.
In c++ I would use multidimensional arrays in a different way. There are many topics on the internet about it.
This topic explains how you could do it using a char***. E.g.:
char getMatrixData(char*** matrix, int x, int y, int z)
{
return matrix[x][y][z];
}
int main()
{
char ***matrix = new char**[2];
for (auto i = 0; i < 2; i++)
{
matrix[i] = new char*[2];
for (auto j = 0; j < 2; j++)
{
matrix[i][j] = new char[2];
}
}
getMatrixData(matrix, 1, 1, 1);
// N.B.! you should normally free the memory using delete []!!
// But in this case the program ends, so the memory is freed anyhow.
return 0;
}
But you could also use the std::vector type
#include <vector>
using std::vector;
using CharVector1D = vector<char>;
using CharVector2D = vector<CharVector1D>;
using CharVector3D = vector<CharVector2D>;
char getMatrixData(CharVector3D const& matrix, int x, int y, int z)
{
return matrix[x][y][z];
}
int main()
{
CharVector3D matrix(2, CharVector2D(2, CharVector1D(2)));
getMatrixData(matrix, 1, 1, 1);
return 0;
}
However, c++ is supposed to be an object oriented programming language. So it is probably better to define an matrix object.
#include <vector>
using std::vector;
template <class T>
class Matrix3D
{
private:
size_t _sizeX;
size_t _sizeY;
size_t _sizeZ;
vector<T> _data;
public:
Matrix3D(size_t const x_size, size_t const y_size, size_t const z_size)
: _sizeX(x_size)
, _sizeY(y_size)
, _sizeZ(z_size)
, _data(vector<T> (x_size*y_size*z_size))
{}
T GetData(size_t const x, size_t const y, size_t const z) const
{
return _data.at(x + (_sizeX * (y + (_sizeY * z))));
}
};
int main()
{
Matrix3D<char> matrix(2, 2, 2);
matrix.GetData(1, 1, 1);
return 0;
}
I keep getting the error message, exc_bad_access code=1 for my line
asize = *(***(y) + **(y + 1));
in the summation function. I dont quite understand what to do with this error, but i know that it is not a memory leak.
I am trying to get the values stored in the y pointer array, add them, and store it in the variable asize.
void allocArr (int **&x, int ***&y, int **&q, int ****&z)
{
x = new int *[2];
y = new int **(&*x);
q = &*x;
z = new int ***(&q);
}
void putArr(int **&x, int &size1, int &size2)
{
*(x) = *new int* [size1];
*(x + 1) = *new int* [size2];
}
void Input (int **&x, int *&arr, int &size1,int &size2, int a, int b)
{
cout << "Please enter 2 non-negative integer values: "<< endl;
checkVal(size1, a);
checkVal(size2, b);
putArr(x, size1, size2);
arr[0] = size1;
arr[1] = size2;
cout << x[0];
}
void summation(int ***&y, int *&arr)
{
int asize = 0;
asize = *(***(y) + **(y + 1));
**y[2] = *new int [asize];
*(arr + 2) = asize;
}
int main()
{
int size1, size2;
int a = 1, b = 2;
int** x;
int*** y;
int** q;
int**** z;
int *arr = new int [2];
allocArr(x, y, q, z);
Input(x, arr, size1, size2, a, b);
summation(y, arr);
display(z);
}
Thank you for the help. Im really struggling here...
Not sure how you got started with the code. The code can be simplified quite a bit to help you, and readers of your code, understand what's going on.
Function allocArr
The lines
y = new int **(&*x);
q = &*x;
can be
y = new int **(x); // &*x == x
q = x;
Function putArr
You have the function declaration as:
void putArr(int **&x, int &size1, int &size2)
It can be changed to:
void putArr(int **x, int size1, int size2)
without changing how you are using the variables.
Your code in the function seems strange. Did you mean for x[0] and x[1] to point to an array of size1 and size2 ints, respectively? If you did, the code would be:
x[0] = new int[size1];
x[1] = new int[size2];
If you don't mean the above, it's hard to figure out what you are trying to do with your code.
Function Input
You have the function declaration as:
void Input (int **&x, int *&arr, int &size1,int &size2, int a, int b)
It can be changed to:
void Input (int **x, int *arr, int &size1,int &size2, int a, int b)
without changing how you are using the variables.
You are calling a function checkVal, but your posted code doesn't have that function. It's not clear what that function is doing. You have the line
cout << "Please enter 2 non-negative integer values: "<< endl;
just before the calls to checkVal. Presumably, checkVal reads the input and stores them in size1 in the first call and size2 in the second call. It's not clear how the second argument to checkVal is used.
And then, you have the line:
cout << x[0];
It's not clear what you wish to accomplish from printing an int* to cout. Perhaps it was part of your debugging code. The line doesn't change anything else in the program. It's just strange to see it there.
Function summation
You have the function declaration as:
void summation(int ***&y, int *&arr)
It can be changed to:
void summation(int ***y, int *arr)
without changing how you are using the variables.
In this function, you have the expression:
asize = *(***(y) + **(y + 1));
What do you get when you evaluate ***(y)?
***(y) = **(*y) = **(x) = *(*x) = *(x[0]) = uninitialized value from the line:
x[0] = new int[size1];
You will get unpredictable behavior when you use an uninitialized value.
The second term of the line, **(y + 1) is the worse culprit.
You allocated memory for y as:
y = new int **(&*x);
It's a pointer to a single object of type int**, not an array. y+1 is not a valid pointer. Dereferencing (y+1) leads to undefined behavior. In your case, you are seeing exc_bad_access, which makes sense now since you are accessing memory that is out of bounds.
Since I don't know what you are trying to compute in that expression, it's hard for me to suggest something useful. I hope you have enough to take it from here.
I get a segmentation fault when reading the second element of h array inside the g function. Strangely, when debugging can I actually watch the array content. I think that besides this curious thing that shows that the data is there, I have done something wrong. Thanks in advance.
#include <iostream>
using namespace std;
void function(void function_passed(double* [], int), int n);
void g(double* [] ,int n_g);
int main()
{
function(g,5);
return 0;
}
void g(double* h[], int n_g)
{
for (int i = 0; i < n_g; i++)
cout << i << " "<< *h[i] << endl;
}
void function(void function_passed(double* [], int ), int n)
{
double * h = new double[n];
for (int i=0;i<n;i++)
h[i] = i + 10;
function_passed(&h,n);
delete[] h;
}
void func(void g(double* [],int n ), int n)
{
double * h = new double[n];
for (int i=0;i<n;i++)
h[i] = i;
g(&h,n);
delete[] h;
}
Operator precedence has bitten you. Inside g:
*h[i] is parsed as *(h[i]) but what you want is (*h)[i].
*h[i] is okay for the first iteration, but in the second one (and all subsequent) you're dereferencing an invalid pointer h+i.
On the second thought, you're actually invoking undefined behavior - pointer arithmetic is valid only between pointers that point to the same array.
using namespace std;
int addition (int a, int b)
{
return (a+b);
}
int subtraction (int a, int b)
{
return (a-b);
}
int operation (int x, int y, int (*functocall)(int,int))
{
int g;
g = (*functocall)(x,y);
return(g);
}
int main()
{
int m,n;
int (*minus)(int,int) = subtraction;
m = operation (7,5,addition);
n = operation (20,m,minus);
cout << n;
return 0;
}
Can anybody explain this line for me
int (*minus)(int,int) = subtraction;
Thanks a lot!
int (*minus)(int,int) = subtraction; is creating a variable called minus and assigning it a pointer to the function called subtraction. if the code is valid then the function subtraction would be declared int subtraction(int a, int b);.
the best way to deal with function pointers is to make them readable using typedef.
example:
typedef int (*math_op)(int,int); // new types is math_op
int subtraction (int a, int b)
{
return (a-b);
}
math_op minus = subtraction;
later on these can be called like they are normal functions.
example:
int result = minus(10, 2); // result is now set to 8
your code rewritten:
using namespace std;
typedef int (*math_op)(int,int); // new types is math_op
int addition (int a, int b)
{
return (a+b);
}
int subtraction (int a, int b)
{
return (a-b);
}
int operation (int x, int y, math_op functocall)
{
int g;
g = functocall(x,y);
return(g);
}
int main()
{
int m,n;
math_op minus = subtraction;
m = operation (7,5,addition);
n = operation (20,m,minus);
cout << n;
return 0;
}
"minus" is a name of a variable which is a pointer to a function taking two int arguments and returning another int.
The function called "operation" takes 3 arguments: 2 ints and a pointer to a function which operates on 2 ints and return another one. When invoked, the operation function applies argument 3 to the arguments 1 and 2.
int (*minus)(int,int)
says
A pointer to a function taking two ints as arguments returning an int.
The parentheses around (*minus) are there to make sure that the asterisk binds to the name of the typedef and not the return type (i.e., the function does not return an int*).
I'm trying to learn templates in C++ and one of the things I was trying was to code a map function like the ones you typically find in functional languages. The idea was something like this:
template <class X> X * myMap(X * func(X), X * array, int size)
{
X * temp;
for(int i = 0, i < size, i++) {temp[i] = (*func)(array[i]);}
return temp;
}
But when I try to use this in:
int test(int k) { return 2 * k;}
int main(void)
{
int k[5] = {1,2,3,4,5};
int *q = new int[5];
q = myMap(&test, k, 5);
for(int i=0; i<5; i++) {cout << q[i];}
delete [] q;
return 0;
}
I got a type mismatch error when compiling:
main.cpp:25: error: no matching function for call to ‘myMap(int (*)(int), int [5], int)’
I tried to change it to:
int main(void)
{
int *k = new int[5];
int *q = new int[5];
for(int i=0; i<5;i++) {k[i] = i;}
q = myMap(&test, k, 5);
for(int i=0; i<5; i++) {cout << q[i];}
delete [] q;
return 0;
}
The error message changes to:
main.cpp:26: error: no matching function for call to ‘myMap(int (*)(int), int*&, int)’
This is probably something very wrong, but I can't find where.
EDIT: The errors where:
1) I mistyped the pointer to function. It's X (*func)(X) instead of X * func(X) .
2) forgot to allocate temp. Must do X * temp = new X[size].
3) are there any more errors?
X * func(X) does not say what you think it says. You want X (*func)(X).
You're just getting the syntax for a function pointer wrong here. You want to say:
template <class X>
X* myMap(X (* func)(X), X * array, int size)
{
...
}
To make this function more generic, use a template parameter instead of a function pointer so you can use both plain function pointers and C++ function objects (functors).
template <class X, class F>
X* myMap(F func, X * array, int size)
{
...
}
You were very close. Just missing parens around X(*func)(X). Couple other syntax errors, fixed here:
#include <iostream>
using namespace std;
template <class X> X * myMap(X(*func)(X), X * array, int size)
{
X * temp;
for(int i = 0; i < size; i++) {temp[i] = (*func)(array[i]);}
return temp;
}
int test(int k) { return 2 * k;}
int main(void)
{
int k[5] = {1,2,3,4,5};
int *q = new int[5];
q = myMap(&test, k, 5);
for(int i=0; i<5; i++) {cout << q[i];}
delete [] q;
return 0;
}
You're not calling your templated MyMap function, you'reattempting to call a non-templated MyMap function. Try q= MyMap(.....)