I am trying to do a large matrix multiplication, e.g. 1000x1000. Unfortunately, it only works for very small matrices. For the big ones, the program just turns on and that's all - no results. Here's the code:
#include <iostream>
using namespace std;
int main() {
int matrix_1_row;
int matrix_1_column;
matrix_1_row = 10;
matrix_1_column = 10;
int** array_1 = new int* [matrix_1_row];
// dynamically allocate memory of size matrix_1_column for each row
for (int i = 0; i < matrix_1_row; i++)
{
array_1[i] = new int[matrix_1_column];
}
// assign values to allocated memory
for (int i = 0; i < matrix_1_row; i++)
{
for (int j = 0; j < matrix_1_column; j++)
{
array_1[i][j] = 3;
}
}
int matrix_2_row;
int matrix_2_column;
matrix_2_row = 10;
matrix_2_column = 10;
// dynamically create array of pointers of size matrix_2_row
int** array_2 = new int* [matrix_2_row];
// dynamically allocate memory of size matrix_2_column for each row
for (int i = 0; i < matrix_2_row; i++)
{
array_2[i] = new int[matrix_2_column];
}
// assign values to allocated memory
for (int i = 0; i < matrix_2_row; i++)
{
for (int j = 0; j < matrix_2_column; j++)
{
array_2[i][j] = 2;
}
}
// Result
int result_row = matrix_1_row;
int result_column = matrix_2_column;
// dynamically create array of pointers of size result_row
int** array_3 = new int* [result_row];
// dynamically allocate memory of size result_column for each row
for (int i = 0; i < result_row; i++)
{
array_3[i] = new int[result_column];
}
// Matrix multiplication
for (int i = 0; i < matrix_1_row; i++)
{
for (int j = 0; j < matrix_2_column; j++)
{
array_3[i][j] = 0;
for (int k = 0; k < matrix_1_column; k++)
{
array_3[i][j] += array_1[i][k] * array_2[k][j];
}
}
}
//RESULTS
for (int i = 0; i < result_row; i++)
{
for (int j = 0; j < result_column; j++)
{
std::cout << array_3[i][j] << "\t";
}
}
// deallocate memory using delete[] operator 1st matrix
for (int i = 0; i < matrix_1_row; i++)
{
delete[] array_1[i];
}
delete[] array_1;
// deallocate memory using delete[] operator 2nd matrix
for (int i = 0; i < matrix_2_row; i++)
{
delete[] array_2[i];
}
delete[] array_2;
// deallocate memory using delete[] operator result
for (int i = 0; i < result_row; i++)
{
delete[] array_3[i];
}
delete[] array_3;
return 0;
}
Anyone have an idea how to fix it? At what point did I go wrong? I used pointers, dynamic memory allocation.
Instead of working with arrays directly named as matrix, try something simple and scalable, then optimize. Something like this:
class matrix
{
private:
// sub-matrices
std::shared_ptr<matrix> c11;
std::shared_ptr<matrix> c12;
std::shared_ptr<matrix> c21;
std::shared_ptr<matrix> c22;
// properties
const int n;
const int depth;
const int maxDepth;
// this should be shared-ptr too. Too lazy.
int data[16]; // lowest level matrix = 4x4 without sub matrix
// multiplication memory
std::shared_ptr<std::vector<matrix>> m;
public:
matrix(const int nP=4,const int depthP=0,const int maxDepthP=1):
n(nP),depth(depthP),maxDepth(maxDepthP)
{
if(depth<maxDepth)
{
// allocate c11,c22,c21,c22
// allocate m1,m2,m3,...m7
}
}
// matrix-matrix multiplication
matrix operator * (const matrix & mat)
{
// allocate result
// multiply
if(depth!=maxDepth)
{
// Strassen's multiplication algorithm
*m[0] = (*c11 + *c22) * (*mat.c11 + *mat.c22);
...
*m[6] = (*c12 - *c22) * (*mat.c21 + *mat.c22);
*c11 = *m[0] + *m[3] - *m[4] + *m[6];
..
*c22 = ..
}
else
{
// innermost submatrices (4x4) multiplied normally
result.data[0] = data[0]*mat.data[0] + ....
...
result.data[15]= ...
}
return result;
}
// matrix-matrix adder
matrix operator + (const matrix & mat)
{
// allocate result
// add
if(depth!=maxDepth)
{
*result.c11 = *c11 + *mat.c11;
*result.c12 = *c12 + *mat.c12;
*result.c21 = *c21 + *mat.c21;
*result.c22 = *c22 + *mat.c22;
}
else
{
// innermost matrix
result.data[0] = ...
}
return result;
}
};
This way, it costs less time-complexity and still looks simple to read. After it works, you can use single-block of matrix array inside of class to optimize for more speed, preferably only allocating once at root matrix and use
std::span
for access from submatrices for newer C++ versions. It is even parallelizable easily as each matrix can distribute its work to at least 4 threads and they can to 16 threads, 64 threads, etc. But of course too many threads are just as bad as too many allocations and should be optimized in a better way.
I am making a simple game, which needs me to create a board of size defined by the user.
I have been writing a function that is supposed to return the board (matrix) that I will be using for my game, but I can't seem to get it to work.
I tried using the nested for loop method to print out the matrix in the main function, but I have troubles implementing it and returning it from a function.
int* boardStateDead(int width, int height){
int* board_dead_state[width][height];
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
board_dead_state[i][j] = 0;
}
}
return board_dead_state;
}
I expect the function to be able to return a pointer to the matrix that I just made.
You are creating your board array in stack and that gets deleted after it goes out of scope. Also you are creating it as an array of integer pointers instead of array of integers.
What i suggest is you create it with new statement:
int* board_dead_state = new[width*height];
Then setting you initial values either use:
memset(board_dead_state, 0, width*height*sizeof(int));
or modify your for loop to:
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
int offset = i * width + j
board_dead_state[offset]= 0;
}
}
After you return the pointer from the function, you are responsible for deallocating it using delete[] statement.
You could make a board class to handle the allocation and deallocation when needed.
I suggest you create a simple class or struct to hold your board state. Internally, use a std::vector so you don't need to worry about managing memory.
You can even overload operator[](int) to make it function like a 2D array, if you want.
#include <vector>
class Board
{
public:
Board(int width, int height)
: mWidth(width)
, mHeight(height)
, mState(width * height)
{}
int* operator[](int row) { return mState.data() + row * mWidth; }
const int* operator[](int row) const { return mState.data() + row * mWidth; }
int Width() const { return mWidth; }
int Height() const { return mHeight; }
private:
int mWidth, mHeight;
std::vector<int> mState;
};
Now, simply construct it when you know what size it needs to be:
Board board(width, height);
The constructor for std::vector will initialize all the values to zero.
You could print this out by accessing it with the methods I've added:
for (int row = 0; row < board.Height(); row++)
{
for (int col = 0; col < board.Width(); col++)
{
std::cout << ' ' << board[row][col];
}
std::cout << std::endl;
}
Or better still, make another method on the board, such as Print().
Here's how to use do it in your code:
int** boardStateDead(int width, int height){
int** board_dead_state = new int*[height];
for(int i = 0; i < height; i++){
board_dead_state[i] = new int[width];
for(int j = 0; j < width; j++){
board_dead_state[i][j] = 0;
}
}
return board_dead_state;
}
Then you get it like this:
int** state = boardStateDead(someWidth, someHeight);
And access its element like state[i][j]. And finally, but probably, most importantly, when you're done using it, free its memory like this:
for (int i = 0; i < height; i++)
{
delete[] state[i];
}
delete[] state;
My code has a 4D matrix in it for some math problem solving
int**** Sads = new int***[inputImage->HeightLines];
for (size_t i = 0; i < inputImage->HeightLines; i++)
{
Sads[i] = new int**[inputImage->WidthColumns];
for (size_t j = 0; j < inputImage->WidthColumns; j++)
{
Sads[i][j] = new int*[W_SIZE];
for (size_t k = 0; k < W_SIZE; k++)
{
Sads[i][j][k] = new int[W_SIZE];
}
}
}
//do something with Sads...
for (int i = 0; i < inputImage->HeightLines; i++)
{
int*** tempI = Sads[i];
for (int j = 0; j < inputImage->WidthColumns; j++)
{
int** tempJ = tempI[j];
for (int k = 0; k < W_SIZE; k++)
{
delete[] tempJ[k];
}
delete[] Sads[i][j];
}
delete[] Sads[i];
}
delete[] Sads;
The sizes are very large WidthColumns = 2018, HeightLines = 1332, W_SIZE =7, the memory allocation is very fast but the memory deallocation (delete) is very slow.
Is there a way to optimize it?
I tired openMP but it throws unrelated errors of missing DLL which are there... if I removed the #pragma omp parallel for everything works fine. but slow...
Using a pointer to a pointer to... is a bad idea because it will fragment your data a lot.
I would create a class ta manage the indices transform and use 1D array, it's a bit more complicated but it will be faster.
Anyway, a trick: nothing prevent you to build your int**** with pointers to a zone in memory that isn't sparse (1D array you preallocated) and then use it as a 4D array.
I'd probably be inclined to use a std::vector. Now memory allocation is taken care of for me (in one allocation/deallocation) and I get free copy/move semantics.
All I have to do is provide the offset calculations:
#include <vector>
#include <cstddef>
struct vector4
{
vector4(std::size_t lines, std::size_t columns)
: lines_(lines), columns_(columns)
, storage_(totalSize())
{}
auto totalSize() const -> std::size_t
{
return lines_ * columns_ * w_size * w_size;
}
int* at(std::size_t a)
{
return storage_.data() + (a * columns_ * w_size * w_size);
}
int* at(std::size_t a, std::size_t b)
{
return at(a) + (b * w_size * w_size);
}
int* at(std::size_t a, std::size_t b, std::size_t c)
{
return at(a, b) + (c * w_size);
}
int& at(std::size_t a, std::size_t b, std::size_t c, std::size_t d)
{
return *(at(a, b, c) + d);
}
private:
std::size_t lines_, columns_;
static constexpr std::size_t w_size = 32; // ?
std::vector<int> storage_;
};
int main()
{
auto v = vector4(20, 20);
v.at(3, 2, 5, 1) = 6;
// other things
// now let it go out of scope
}
The correct way to create, use, and delete a 4D array is this, using the closure of the statement group to delete the automatic variables.
{
const int H = 10;
const int I = 10;
const int J = 10;
const int K = 10;
int h = 0;
int i = 0;
int j = 0;
int k = 0;
int fourDimArray [H][I][J][K];
fourDimArray[h][i][j][k] = 0;
}
If you have a need to dynamically allocate, then use either STL's list or vector class or use something like this with perhaps inline methods to calculate the index of the 1D array from the 4D array indices if you need blazing speed.
int * fourDimArrayAsOneDim = new int[H*I*J*K];
fourDimArrayAsOneDim[indexFromIndices(h, i, j, k)] = 0;
delete [] fourDimArrayAsOneDim;
I have written a piece of code in C++. I took the first part from search engine results.
1) What is the meaning of defining a function using double **filter_2d? Can we define a function using a pointer?
2) I am confused about the following line:
double **filt_out = filter_2d(A, 3, 3, B, 2, 1);
It is not working properly, and I do not understand why.
#include <iostream>
#include <stddef.h>
#include <cmath>
#include <fftw3.h>
using namespace std;
void filter_2d(double** image, int width_image, int height_image, double** kernel, int width_kernel, int height_kernel, double *** OutImg)
{
double **output = *OutImg;
int i, j, p, q;
//this is the case of 'full' option selected in matlab
//double **output = (double **)malloc(sizeof(double *)*(width_image + width_kernel - 1));
for (i = 0; i<width_image + width_kernel - 1; i++)
{
output[i] = (double *)malloc(sizeof(double)*(height_image + height_kernel - 1));
}
//for each point in the output
for (i = 0; i<width_image + width_kernel - 1; i++)
{
for (j = 0; j<height_image + height_kernel - 1; j++)
{
output[i][j] = 0;
//kernel(p,q)*image(i-p, j-q)
for (p = 0; p<width_kernel; p++)
{
//avoid unnecessary comparisons
if (i - p < 0)
{
break;
}
else if (i - p < width_image)
{
for (q = 0; q<height_kernel; q++)
{
//idem as above
if (j - q < 0)
{
break;
}
else if (j - q < width_image)
{
output[i][j] += kernel[p][q] * image[i - p][j - q];
}
}
}
}
}
}
}
int main()
{
double ** OutImage = 0;
OutImage = (double **)malloc(sizeof(double *)*(3 * 3));
double A[3][3] = { { 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 } };
double *A_ptr[9];
for (int i = 0; i < 10; i++)
{
A_ptr[i] = A[i];
}
double B[1][2] = { 1, 2 };
double *B_ptr[2];
for (int i = 0; i < 2; i++)
{
B_ptr[i] = B[i];
}
//Error in the below line
filter_2d(A_ptr, 3, 3, B_ptr, 2, 1, &OutImage); //unable to understand
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 4; j++)
cout << *OutImage << endl;
}
system("PAUSE");
return 0;
}
Pointer Declaration
General Format:
data_type *pointer_name;
A pointer declaration such as,
int *numberPtr;
declares numberPtr as a variable that points to an integer variable. Its content is a memory address.
The * indicates that the variable being declared is a pointer variable instead of a normal variable.
Consider the following declaration :
int *numberPtr, number = 20;
In this case, two memory address have been reserved, associated with the names numberPtr and number.
The value in variable number is of type integer, and the value in variable numberPtr is an address for another memory location.
Example
// create a 2D array dynamically
int rows, columns, i, j;
int **matrix;
cin >> rows >> columns;
matrix = new int*[rows];
for(i=0; i<rows; i++)
matrix[i] = new int[columns];
Your function expects double** and your are passing double [3][3]. There is no implicit cast for these types.
You need to create you array in the main() as double ** and use it as the argument in the function call.
The question - conversion of 2D array to pointer-to-pointer should help you in achieving what you are trying to do.
Your cout does not seem correct as well. You are considering filt_out as a 2D array instead of pointer.
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 4; j++)
cout << **(filt_out + i + j) << endl; //changed here
}
I have analysed your code and I think I have found some issues in it.
Here is the new code:
#include <iostream>
#include <stdlib.h>
using namespace std;
double** filter_2d(double** image, int width_image, int height_image, double** kernel, int width_kernel, int height_kernel)
{
int i, j, p, q;
//this is the case of 'full' option selected in matlab
double **output = (double **)malloc(sizeof(double *) * (width_image + width_kernel - 1));
for (i = 0; i<width_image + width_kernel - 1; i++)
output[i] = (double *)malloc(sizeof(double) * (height_image + height_kernel - 1));
//for each point in the output
for (i = 0; i<width_image + width_kernel - 1; i++)
for (j = 0; j<height_image + height_kernel - 1; j++)
{
output[i][j] = 0;
//kernel(p,q)*image(i-p, j-q)
for (p = 0; p<width_kernel; p++)
{
//avoid unnecessary comparisons
if (i - p < 0)
{
break;
}
else if (i - p < width_image)
{
for (q = 0; q<height_kernel; q++)
{
//idem as above
if (j - q < 0)
break;
else if (j - q < width_image)
output[i][j] += kernel[p][q] * image[i - p][j - q];
}
}
}
}
return output;
}
int main()
{
double A[3][3] = { { 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 } };
double *A_ptr[9];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j ++)
A_ptr[i * 3 + j] = &(A[i][j]);
double B[1][2] = { 1, 2 };
double *B_ptr[2];
for (int i = 0; i < 1; i++)
for (int j = 0; j < 2; j ++)
B_ptr[i * 1 + j] = &(B[i][j]);
//no more errors in the function call
double **OutImage = filter_2d(A_ptr, 3, 3, B_ptr, 2, 1);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
cout << OutImage[i][j] << " ";
cout << endl;
}
return 0;
}
I thought a better idea would be that function filter_2d returns a pointer to the output matrix. The output matrix is dynamically allocated with malloc inside the function, so it will not be lost (and you can get the computed values in the matrix) if you return the address to it and store it back in main.
You can see here a comparison between stack memory and variables local to a function vs heap memory and variables allocated with malloc stack vs heap
Now I will talk about some problems I found in the main function. The first problem was at the initialization of the arrays of pointers A_ptr and B_ptr.
double *A_ptr[9];
for (int i = 0; i < 10; i++)
{
A_ptr[i] = A[i];
}
and
double *B_ptr[2];
for (int i = 0; i < 2; i++)
{
B_ptr[i] = B[i];
}
From what I understood in your code the elements of A_ptr and B_ptr were pointers to each element of the arrays A and B.
So, as A_ptr and B_ptr are linearized matrices, you have to be careful as to give the correct addresses of the corresponding elements from arrays A and B.
If you take a matrix M and linearize it into a matrix N, then element M[i][j] will go to N[i * number_of_columns_from_M + j].
Another problem was the limits of i and j in the for cycles where you were printing the results.
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 4; j++)
cout << *OutImage << endl;
}
From what I calculated, in filter_2d function you allocate a matrix of 4 lines and 3 columns. In those cycles you were assuming that OutImage has 5 lines and 4 columns.
The last problem was the printing of the elements from OutImage.
cout << *OutImage << endl;
OutImage as you declared in your code was an array of 9 pointers (don't understand why you did that). With the above instruction you are repeatedly printing the first element of OutImage array (which is an address as OutImage is an array of 9 pointers), so that is why you were seeing only addresses printed.
I am not sure if the numbers printing now on the screen are correct, as I don't know what mathematical computation is done in filter_2d.
It can help to read * in C++ pointer-contexts as pointer to.
int* a;
a is a pointer to int.
int** b;
b is a pointer to pointer to int.
b = &a;
a is a pointer to int. &a is the address of a pointer to int. b is a pointer to a pointer to int.
*a = 10;
store 10 in the memory pointed to by a.
**b = 20;
store 20 in the memory pointed to by the int* that b points to.
#include <iostream>
int main()
{
int i = 1234;
int* a;
int** b;
std::cout << "i is " << i << ", it's address is " << i << "\n";
a = &i;
std::cout << "a = " << a << ", *a = " << *a << ", its address is " << &a << "\n";
b = &a;
std::cout << "b = " << b << ", *b = " << *b << ", **b = " << **b << ", its address is " << &b << "\n";
}
Live demo: http://ideone.com/OpCro4
Your function "filter_2d" returns the address of a pointer. It also expects the first parameter to be the address of a pointer.
This is often used as a way to allow functions to say "give me the address of a pointer and I will populate it for you" but C++ also uses pointers to pass arrays.
int a[100];
f(a);
The program could pass all 100 addresses to f() which would either require 100 ints on the stack or 100 registers.
Or alternatively, it could pass the address of the first int in a. And in C and C++ that's generally how arrays work - they are operated on as an array and an offset.
int a[100];
int* b = a; // b points to the first element in a
// these two mean the same thing
a[90];
*(b + 90);
// undefined behavior
*(b + 100); // the 101st element of a, i.e. invalid
The downside: Pointers only know about the element they point to, they don't intrinsically know anything about array lengths.
Lastly, instead of SYSTEM("PAUSE") either use 'Ctrl+F5' to start without debugging (which will automatically prompt you to hit return after execution) or use 'F11' to step into your program.
Your code has 2 problems:
First, I'm assuming the output image will have the same size as an input image so it must be allocated like this:
(double **)malloc(sizeof(double *)*(width_image * height_image));
Second, you define a function that will return a 2D pointer, but unfortunately, you declare this 2D pointer inside the function itself which means that you define a local variable pointer, In most cases once you return this value it will be totally wrong and it's not the one which is allocated inside the function itself.
To solve the problem you can choose one of these two solutions:
You can define a global 2D pointer, and inside your function it can be allocated, so you don't need to define your function to return 2D pointer.
The second solution is to define the 2D pointer that will store the result in the caller function, the caller function will allocate the required size for that pointer and pass it to the callee function (i.e filter_2d), when it pass it, it will be passed by its address, so in the filter_2d definition we will add an extra argument as a 3D POINTER to store the result as the following:
//Define these 2 lines in the main function.
double ** OutImage = null;
OutImage = (double **)malloc(sizeof(double *)*(width_image * height_image));
To pass the OutImage to the filter_2d function:
filter_2d(A_ptr, 3, 3, B_ptr, 2, 1, &OutImage);
The definition of the filter_2d function should be:
void filter_2d(double** image, int width_image, int height_image, double** kernel, int width_kernel, int height_kernel, double *** OutImg)
Inside filter_2d you can define your local variable as the following:
double **output = *OutImg;
Hope this calrrification will help you.
I have written a piece of code in C++. I took the first part from
search engine results.
Are you serious? Not sure how to understand that. It's not a debugging site. You're supposed to do the effort first.
Anyway, your code is mostly C. The only piece of code reminding me of C++ is the console output. So let me try if I can help... because I like.
1) What is the meaning of defining a function using double **filter_2d? Can we define a function using a pointer?
This means that the result of the function is a pointer to a pointer of type double. Break it down like this:
**filt_out is of type double - used to access a double value; popular use in 2D arrays to access the 2nd dimension, i.e. the row and the column of a 2D array.
*filt_out is of type double * - used to access a pointer to a double value; popular use in 2D arrays to access the 1st dimension, i.e. the row of a 2D array.
filt_out is of type double ** - used to access a pointer to a pointer to a double value; popular use in 2D arrays to access the array, i.e. the allocated memory address for the 2D array.
You can define a function using a simple pointer, but it is not suitable for 2D arrays. Read the items above.
2) I am confused about the following line:
double **filt_out = filter_2d(A, 3, 3, B, 2, 1); It is not working
properly, and I do not understand why.
Does not make sense to me. filter_2d's return type is voidand thus I don't see why would want to assign the returned value to a pointer to a pointer to a double
It is not working properly, and I do not understand why.
Me neither, yet. But to be honest, it sounds more like a debugging request than a question that merits votes. In particular you give us the impression that you did not do your homework learning C/C++ first of all, and secondly copied code from a search engine and ask the community to solve that for you.
Some flaws I believe you want to have a closer look at:
(I'll use mostly C syntax)
OutImage = (double **)malloc(sizeof(double *)*(3 * 3));
It does not look right to me. Please verify.
I think OutImage is supposed to be a 2D array (the image) and thus **OutImage points to an element (2nd dimension, you want to access row and column) of the 2D array.
Also since it is a 2D array, you need to initialize the 1st dimension first (i.e. the rows) and then the 2nd dimension (i.e. the columns).
So I would suggest something like this:
//three rows of size for type double*
OutImage = (double **) malloc(sizeof(double *) * 3);
//three columns of size of type double
for (int i=0; i<3; i++)
OutImage[i] = (double *) malloc(sizeof(double) * 4);
This way you can access using OutImage[row][column]. I believe it's less error prone. I put the size of the columns to 4 according to the calculation in the function filter_2d which calculates the widths and the heights (The width remains the same with parameters given, the height increases by one dimension).
Also (see below) later in the function filter_2d I'd remove the memory allocation, since it is already done here.
Not sure what you want to achieve with this, but I think that...
double *A_ptr[9];
for (int i = 0; i < 10; i++)
{
A_ptr[i] = A[i];
}
is just wrong on so many levels.
10 does not make sense; indices go from 0 to 8
A[i] has size 3 while A_ptr[i] has size 9
what were you thinking Sam?
Considering the use of A_ptr (and the way you access it) in the function filter_2d above I would think you want to do something analogue to above 2D array.
double ** A_ptr = (double **) malloc(sizeof (double *) * 3);
for (int i = 0; i < 3; i++)
A_ptr[i] = (double *) malloc(sizeof (double) * 3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
A_ptr[i][j] = A[i][j];
}
}
double B[1][2] = { 1, 2 };
double *B_ptr[2];
for (int i = 0; i < 2; i++)
{
B_ptr[i] = B[i];
}
Similar to above.
B[i] is of size 1, so only index 0 makes sense
Damn Sam, what were you thinking again?
You call filter with following parameters:
A_ptr: a 2D array copy of A (image)
3: size of 1st dimension of image
3: size of 2nd dimension of image
B_ptr: a 2D array copy of B (kernel)
2: size of 1st dimension of kernel - Should be switched with the next one
1: size of 2nd dimension of kernel - Should be switched with the previous one
&OutImage: address of the pointer to the resulting filtered image (the parameter is a pointer to **OutImage actually)? I think you want to preserve the pointer after the function call, isn't it? Sounds OK to me.
filter_2d(A_ptr, 3, 3, B_ptr, 2, 1, &OutImage);
You defined B_ptr as a copy of B which has dimensions [1][2], but you pass 2 as 1st dimension and 1 as 2nd dimension to the function. Either switch the dimensions of B/B_ptr or switch the two parameters.
In that function I would remove the following code
for (i = 0; i<width_image + width_kernel - 1; i++)
{
output[i] = (double *)malloc(sizeof(double)*(height_image + height_kernel - 1));
}
(See last remark in first bug above when allocating memory for OutImage).
Replace the loop to print the result. Make it look like that:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++)
cout << OutImage[i][j] << endl;
}
I kept the C++ style printing, but actually you could do it simply with C's printf function as well. No need to include iostream really.
So that's it. I compiled your code and run it. Not sure what to expect, but according to your comment it should be
2 5 8 3 8 14 17 6 14 23 26 9
Guess what? I got
1 4 7 6 4 13 16 12 7 22 25 18
Well, I guess at this point, it's your turn now.
Please remember, check where you want to do the memory allocation in
order to have it take into account the new dimensions. I hard
coded it in your example to make it work, more or less.
I would probably allocate a dummy address and then use realloc to increase the size to whatever is needed depending on the parameters.
Remember that in general you would want to free the allocated memory.
I skip it here, since it is a short program.
The program could look like so:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
void filter_2d(double** image, int width_image, int height_image, double** kernel, int width_kernel, int height_kernel, double *** OutImg) {
double **output = *OutImg;
int i, j, p, q;
int rows = width_image + width_kernel - 1;
int cols = height_image + height_kernel - 1;
//rows of size for type double*
output = (double **) realloc(output, sizeof (double *) * rows);
//columns of size of type double
for (int i = 0; i < rows; i++)
output[i] = (double *) malloc(sizeof (double) * cols);
//for each point in the output
for (i = 0; i < width_image + width_kernel - 1; i++) {
for (j = 0; j < height_image + height_kernel - 1; j++) {
output[i][j] = 0;
//kernel(p,q)*image(i-p, j-q)
for (p = 0; p < width_kernel; p++) {
//avoid unnecessary comparisons
if (i - p < 0) {
break;
} else if (i - p < width_image) {
for (q = 0; q < height_kernel; q++) {
//idem as above
if (j - q < 0) {
break;
} else if (j - q < width_image) {
output[i][j] += kernel[p][q] * image[i - p][j - q];
}
}
}
}
}
}
}
int main() {
//allocate dummy memory of size for type double*
double ** OutImage = (double **) malloc(sizeof (double *));
// define image matrix
double A[3][3] = {
{ 1, 2, 3},
{ 4, 5, 6},
{ 7, 8, 9}
};
// copy image matrix
double ** A_ptr = (double **) malloc(sizeof (double *) * 3);
for (int i = 0; i < 3; i++)
A_ptr[i] = (double *) malloc(sizeof (double) * 3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
A_ptr[i][j] = A[i][j];
printf(" %f ", A_ptr[i][j]);
}
}
printf("\n");
//define kernel matrix
double B[1][2] = {
{ 1, 2}
};
//copy kernel matrix
double ** B_ptr = (double **) malloc(sizeof (double *));
B_ptr[0] = (double *) malloc(sizeof (double)*2);
for (int i = 0; i < 1; i++) {
for (int j = 0; j < 2; j++) {
B_ptr[i][j] = B[i][j];
printf(" %f ", B_ptr[i][j]);
}
}
printf("\n");
//call filter
filter_2d(A_ptr, 3, 3, B_ptr, 1, 2, &OutImage);
//print result
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++)
cout << OutImage[i][j] << endl;
}
// No idea what that is
//system("PAUSE");
return 0;
}
P.S.: I just saw that Valy had a good solution.
Yes, functions can returns pointers, or even pointers to pointers. I believe both of your answers are addressed by this thread.
#include <stdlib.h>
int int_sorter( const void *first_arg, const void *second_arg )
{
int first = *(int*)first_arg;
int second = *(int*)second_arg;
if ( first < second )
{
return -1;
}
else if ( first == second )
{
return 0;
}
else
{
return 1;
}
}
int main()
{
int array[10];
int i;
/* fill array */
for ( i = 0; i < 10; ++i )
{
array[ i ] = 10 - i;
}
qsort( array, 10 , sizeof( int ), int_sorter );
for ( i = 0; i < 10; ++i )
{
printf ( "%d\n" ,array[ i ] );
}
}