Calling a pointer function in C++ - c++

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 ] );
}
}

Related

C++ syntax difference: 2D- and 1D-arrays (pointer arithmetic)

Problem
I am learning C++, and am writing code to transpose a 2D array and to reverse a 1D-array.
Please look at the invocations. Why do I have to use reverse(arr, 4) for reverse, whereas I have to use transpose(*in_matrix, *out_matrix) for transpose?
There are two ways of writing each function signature. Both seem to give the same results.
Thank you.
EDIT: I know how to solve it with array-subscript. I am doing it this way deliberately for practice. Now I understand there's no point trying this. However, I have added some notes summarised from the answers below.
Code
#include <iostream>
using namespace std;
const int LENGTH = 2;
const int WIDTH = 3;
void printArray(const int arr[], const int N) {
cout << arr[0];
for (int i = 1; i < N; ++i) {
cout << ", " << arr[i];
}
cout << "\n";
}
// void transpose(int* const input, int* const output) { // both these signatures
void transpose(const int input[], int output[]) { // works (I find the top one clearer)
for (int i = 0; i < WIDTH; ++i) {
for (int j = 0; j < LENGTH; ++j) {
*(output + j * WIDTH + i) = *(input + i * LENGTH + j);
}
}
}
// void reverse(int arr[], const int N) { // both these signatures
void reverse(int* arr, const int N) { // works (I prefer this one)
for (int i = 0; i < N / 2; ++i) {
int temp = *(arr + i);
*(arr + i) = *(arr + N - 1 - i);
*(arr + N - 1 - i) = temp;
}
}
int main() {
int arr[4] = {2,4,6,8};
printArray(arr, 4);
reverse(arr, 4); // this works
// reverse(*arr, 4); // this doesn't work
printArray(arr, 4);
int in_matrix[WIDTH][LENGTH];
in_matrix[0][0] = 1;
in_matrix[0][1] = 2;
in_matrix[1][0] = 3;
in_matrix[1][1] = 4;
in_matrix[2][0] = 5;
in_matrix[2][1] = 6;
int out_matrix[LENGTH][WIDTH];
// transpose(in_matrix, out_matrix); // this doesn't work
transpose(*in_matrix, *out_matrix); // this works
cout << "in_matrix is:\n";
for (int i = 0; i < WIDTH; ++i) {
printArray(in_matrix[i], LENGTH);
}
cout << "out_matrix is:\n";
for (int i = 0; i < LENGTH; ++i) {
printArray(out_matrix[i], WIDTH);
}
return 0;
}
Summary of answers
LESSON: DO NOT USE pointer-arithmetic for 2D-arrays
decay
KEY IDEA: arr -----> &arr[0] type int*
This is also the reason the two function signatures are equivalent.
// transpose(int* const input, int* const output) // alt.
Signature: transpose(const int input[], int output[])
i.e. it expects an array of ints (or equiv., a pointer to an int)
(id)
IDENTITY: a[i] = *(a + i) ALWAYS TRUE
Reason transpose(in_matrix, out_matrix) doesn't work:
decay
out_matrix -----> &out_matrix[0] type int(*)[WIDTH]
Reason transpose(*in_matrix, *out_matrix) works:
(id) decay
*out_matrix = out_matrix[0] -----> &(out_matrix[0])[0]
In C, arrays and pointers are a bit intricately mixed up. An array can be considered as a pointer with some 'size' information attached to it (that is not stored anywhere, but the compiler knows). Hence, sizeof when used on an array gives you the size of the contents of the entire array, while on a pointer, it gives the size of the pointer.
When you pass an array to a function, the size information is lost - in effect, the array decays to a pointer. For most practical purposes, a pointer to a type can be used exactly like a one-dimensional array of that type. The array subscript notation ([]) can also be used to access consecutive elements using a pointer.
However, with 2D arrays, this gets more complicated. 2D arrays and double pointers may use the same access syntax of the form a[i][j] but they are not interchangeable. A 2D array decays to a pointer to an array while a double pointer is a pointer to a pointer.
Coming back to your question, the two ways of writing the function signatures are essentially equivalent because 1D arrays decay to pointers when passed to functions. So void reverse(int* arr, const int N) is the same as void reverse(int arr[], const int N).
In your transpose function however, you are passing a 2D array. It would decay to a pointer to an array. But in your function declaration, you are accepting these arguments as arrays (or in effect, pointers). This still works fine because of the quirks of C. A 2D array can be also treated as one big 1D array with the rows laid out consecutively one after the other. It is, however, not the best approach. This also reflects in the fact that you had to de-reference the array names when you passed them to the transpose function, because it expects a 1D array (or a pointer) and not a 2D array (or a pointer to an array).
Also, C/C++ provides a much more elegant way to access arrays than using unwieldy pointer arithmetic. So the following approach is what I would recommend. It should work exactly like the code you originally posted, but would be cleaner and more readable.
#include <iostream>
using namespace std;
const int LENGTH = 2;
const int WIDTH = 3;
void printArray(const int arr[], const int N) {
cout << arr[0];
for (int i = 1; i < N; ++i) {
cout << ", " << arr[i];
}
cout << "\n";
}
void transpose(const int input[][LENGTH], int output[][WIDTH]) {
for (int i = 0; i < WIDTH; ++i) {
for (int j = 0; j < LENGTH; ++j) {
output[j][i] = input[i][j];
}
}
}
void reverse(int* arr, const int N) {
for (int i = 0; i < N / 2; ++i) {
int temp = arr[i];
arr[i] = arr[N - 1 - i];
arr[N - 1 - i] = temp;
}
}
int main() {
int arr[4] = {2,4,6,8};
printArray(arr, 4);
reverse(arr, 4);
printArray(arr, 4);
int in_matrix[WIDTH][LENGTH];
in_matrix[0][0] = 1;
in_matrix[0][1] = 2;
in_matrix[1][0] = 3;
in_matrix[1][1] = 4;
in_matrix[2][0] = 5;
in_matrix[2][1] = 6;
int out_matrix[LENGTH][WIDTH];
transpose(in_matrix, out_matrix);
cout << "in_matrix is:\n";
for (int i = 0; i < WIDTH; ++i) {
printArray(in_matrix[i], LENGTH);
}
cout << "out_matrix is:\n";
for (int i = 0; i < LENGTH; ++i) {
printArray(out_matrix[i], WIDTH);
}
return 0;
}

Fastest way to rotate an 2d array

I am looking for the best algorithm to do a rotation of a row in a 2D array / matrix. Let's say we have
mat[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
I want to shift the element to the left by one, the first row 1 2 3 will then become 2 3 1. The function realizes this by copying each element to the left via dynamical memory allocation.
void rotate_row(const int& row) {
int *temp_row = (int *) (malloc(3));
for (int i = 0; i < 3; ++i) {
temp_row[i % 3] = mat[row][(i + 1) % 3];
}
memcpy(mat[row], temp_row, 3);
free(temp_row);
}
To manipulate any specific row, we simple call the function rotate_row(row).
I don't quite understand malloc thing in C, since I grow up learning a completely new way of dynamical allocation, so I first change it to:
void rotate_rows(const int& row) {
//int *temp_row = (int *) (malloc(3));
int *temp_row = new int[3];
for (int i = 0; i < 3; ++i) {
temp_row[i % 3] = mat[row][(i + 1) % 3];
}
memcpy( mat[row], temp_row, 3);
//free(temp_row);
delete [] temp_row;
temp_row = NULL;
}
My question first is, will simply changing the way of dynamical memory allocation accelerates the code?
Also, I don't think it is necessary to use dynamical memory allocation for my purpose(rotate the row). Is their any better (not necessary the best) algorithm available?
Rotating will not change array size, hence doing it in-place sounds much more performant to me, no need for dynamic memory allocation and freeing previous pointer.
void rotate(int * array, size_t n) {
if (n <= 1)
return;
const int head = array[0];
for (size_t i = 1; i < n; ++i)
array[i - 1] = array[i];
array[n - 1] = head;
}
You can avoid all the dynamic memory allocation, and use the std::rotate algorithm:
#include <algorithm>
#include <iostream>
int main()
{
int mat[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
// rotate left each row by 1
for (int i = 0; i < 3; ++i)
std::rotate(&mat[i][0], &mat[i][1], &mat[i][3]);
for (int i = 0; i < 3; ++i)
std::cout << mat[i][0] << " " << mat[i][1] << " " << mat[i][2] << "\n";
}
Output:
2 3 1
5 6 4
8 9 7
Edit:
Here is a sample of rotating each row by it's row index + 1:
#include <algorithm>
#include <iostream>
int main()
{
int mat[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
// rotate left each row by 1
for (int i = 0; i < 3; ++i)
std::rotate(&mat[i][0], &mat[i][i+1], &mat[i][3]);
for (int i = 0; i < 3; ++i)
std::cout << mat[i][0] << " " << mat[i][1] << " " << mat[i][2] << "\n";
}
Output:
2 3 1
6 4 5
7 8 9
Yes there's a better way and no need to use dynamic memory allocation. You actually don't need another array to solve this.
Here's a sample code:
for(int i = 0; i < n/2; i++){
for(int j = i; j < n-i-1; j++){
int tmp = matrix[i][j];
matrix[i][j] = matrix[n-j-1][i];
matrix[n-j-1][i] = matrix[n-i-1][n-j-1];
matrix[n-i-1][n-j-1] = matrix[j][n-i-1];
matrix[j][n-i-1] = tmp;
}
}
This is pretty straight forward so I think you'll understand the code easily without explanation.

Porting code from C++ to C. How do I deal with this vector and range based loop

I am trying to port to C. Since there's no vectors in C, I used a normal array, but I don't know how I'm going to deal with the ranged based loop on line 18.
for (int u : d[i]) if (dfs(rev[u])) {
par[i] = u;
rev[u] = i;
return true;
}
Complete code:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
const int Maxn = 200;
vector<int> d[Maxn];
int par[Maxn];
int rev[Maxn];
bool vs[Maxn];
bool dfs(int i) {
if (i < 0) return true;
if (vs[i]) return false;
vs[i] = true;
for (int u : d[i]) if (dfs(rev[u])) {
par[i] = u;
rev[u] = i;
return true;
}
return false;
}
int main() {
ios_base::sync_with_stdio(false);
int n;
cin >> n;
string s;
getline(cin, s);
for (int i = 0; i < n; i++) {
getline(cin, s);
stringstream ss(s);
vector<int> mk(n, 1);
mk[i] = 0;
int x;
while (ss >> x)
mk[x] = 0;
for (int x = 0; x < n; x++)
if (mk[x])
d[i].push_back(x);
}
memset(par, -1, sizeof par);
memset(rev, -1, sizeof rev);
for (bool ok = true; ok; ) {
ok = false;
memset(vs, 0, sizeof vs);
for (int i = 0; i < n; i++)
if (par[i] < 0) {
ok |= dfs(i);
}
}
int ans = 0;
for (int i = 0; i < n; i++)
ans += (par[i] < 0);
cout << ans;
}
In C there is no std::vector, the closes would be an array.
int array[] = [ 1, 3, 5, 7, 9 ];
for(int i = 0; i < sizeof array / sizeof *array; ++i)
printf("array[%d] = %d\n", i, array[i]);
If you get a pointer of an array of int, the you have to pass the length of
the array as well, as sizeof arr / sizeof *arr works with arrays only.
void foo(in *array, size_t len)
{
for(int i = 0; i < len; ++i)
printf("array[%d] = %d\n", i, array[i]);
}
void bar(void)
{
int array[] = [ 1, 3, 5, 7, 9 ];
foo(array, sizeof array / sizeof *array);
}
edit 2
I noticed that you've posted your code and that d is declared as vector<int> d[Maxn];. Also taking in consideration your recent comment
So this is an array of vectors. Do you have any idea how i can work with arrays taking that in consideration in C
There a couple of ways to convert the array of vectors in C. But this depends
on your needs. If for example you know that all vectors are going to have the
same size (for example int vectsize = 100), then you can create a two
dimensional array with the sizes1
int Maxn = 200;
int vectsize = 100;
int d[Maxn][vectsize];
memset(d, 0, sizeof d); // initialize all elements with 0
// filling the data
for(int i = 0; i < Maxn; ++i)
{
for(j = 0; j < vectsize; ++j)
d[i][j] = get_value_for(i, j);
}
The the range-loop is very easy:
// assuming that the variables i, par, rev are valid, i between 0 and Maxn-1
for(int j = 0; j < vectsize; ++j)
{
int u = d[i][j];
if (dfs(rev[u])) {
par[i] = u;
rev[u] = i;
return true;
}
}
It gets a little more complicated if you only know one dimension, for example
every vector in the array could have a different size.
d[0].size() --> 10
d[1].size() --> 1
d[2].size() --> 3
...
The you can create an array of pointers to int, but you would have to keep
another array of ints with the length for every d[i] vector.
int Maxn = 200;
int *d[Maxn]; // pointer to int[Maxn] arrays
int vectsize[Maxn];
// initializing with 0
memset(d, 0, sizeof d);
memset(vectsize, 0, sizeof vectsize);
// filling the data
for(int i = 0; i < Maxn; ++i)
{
vectsize[i] = get_length_for(i);
d[i] = malloc(vectsize[i] * sizeof *d[i]);
if(d[i] == NULL)
// error handling
for(j = 0; j < vectsize[i]; ++j)
d[i][j] = get_value_for(i, j);
}
Note that I'm using here (and in the last example) get_length_for() and get_value_for() as placeholders2.
Now your range-base loop would look like this:
// assuming that the variables i, par, rev are valid, i between 0 and Maxn-1
for(int j = 0; j < vectsize[i]; ++j)
{
int u = d[i][j];
if (dfs(rev[u])) {
par[i] = u;
rev[u] = i;
return true;
}
}
At some point however you would have to free the memory:
for(int i = 0; i < Maxn; ++i)
free(d[i]);
The third option would be using a double pointer and using malloc/realloc
to allocate the memory. This is the more general solution, but you have to
take care of memory management and that can be sometimes difficult, especially when you
haven't programmed in C to much. But also in case where both dimension are unknown, this is the way to go:
int Maxn = get_some_maxn_value();
int **d, *vectsize;
d = malloc(Maxn * sizeof *d);
if(d == NULL)
// error handling
vectsize = malloc(Maxn * sizeof *vectsize);
if(vectsize == NULL)
// error handling,
// if you exit the function, don't forget
// to do free(d) first as part of the
// error handling
// initialize all elements with 0
memset(d, 0, Maxn * sizeof *d);
memset(vectsize, 0, Maxn * sizeof *vectsize);
// filling the data (the same as above)
for(int i = 0; i < Maxn; ++i)
{
vectsize[i] = get_length_for(i);
d[i] = malloc(vectsize[i] * sizeof *d[i]);
if(d[i] == NULL)
// error handling
for(j = 0; j < vectsize[i]; ++j)
d[i][j] = get_value_for(i, j);
}
In this case the range-loop would look exactly as for the array of pointers.
Freeing the memory is a little bit different though:
for(int i = 0; i < Maxn; ++i)
free(d[i]);
free(d);
free(vectsize);
Like I said earlier, which one of these three methods to use depends on the way
the original C++ code fills the values, how long the vectors are, etc. Judging
form the C++ code you posted, you read an integer from the user and store it
in n. Then you read more values from the user and push then in the vector
d[i] for all i between 0 and Maxn-1. It seems that all vectors have at
most length n, but because of
if (mk[x])
d[i].push_back(x);
they also could have less than n elements. That's why I think that the third
solution is preferable here.
Annotations
1Prior to C99, Variable Length Arrays (VLA) were not supported, so if you had the
dimension in a variable, you had to use malloc to allocate enough memory.
C99 supports VLAs, but I'm not quite sure how well supported they are and/or
whether your compiler supports them.
I personally don't use them in my code at all, that's why I really don't know. I compiled this examples with GNU
GCC 6.4.0 (on linux) and they worked fine.
The first two options use VLAs, if your compiler doesn't support that, then
you have to use the third option.
For more information about VLAs:
malloced array VS. variable-length-array
What's the difference between a VLA and dynamic memory allocation via malloc?
Variable length array
GCC manual: 6.19 Arrays of Variable Length (in case you ise GCC)
2How you really get this values depends on the original C++ code.
So far I've only looked very briefly over your C++ code. Using the values from
my example get_length_for(0) would return 10, get_length_for(1) would return 1,
get_length_for(2) would return 3, etc.
Assuming d[i] is a vector, this is a similar loop:
for (size_t s = 0; s < d[i].size(); s++)
{
int u = d[i][s];
if (dfs(rev[u]))
{
par[i] = u;
rev[u] = i;
return true;
}
}

C++ check array for duplicates and replace them

i have an array full of values, the array can not contain any duplicate values. for any duplicate value add one to the value. here is the code i have so far, but im still getting duplicates. (randArray is where the values are located).
for (int i = 0; i < sizeof(randArray) - 1; i++) {
for (int j = sizeof(randArray); j == 0; j--) {
if (randArray[i] == randArray[j]) {
randArray[i] == randArray[i] + 1;
}
}
}
You have a typo when incrementing a duplicate:
randArray[i] = randArray[i] + 1; // not ==
Also, the increment might create another duplicate. If it's with an item that comes afterwards there's no problem. But as the array is not sorted, you might not catch such a new duplicate of a value already passed.
Therefore you might need several passes:
bool wasaninc;
do {
wasaninc=false;
for ...
for ...
... // if there is an increment, set wasaninc to true
} while (wasaninc);
Change randArray[i] == randArray[i] + 1; to randArray[i] = randArray[i] + 1;
for (int i = 0; i < sizeof(randArray) - 1; i++) {
for (int j = sizeof(randArray); j == 0; j--) {
if (randArray[i] == randArray[j]) {
randArray[i] = randArray[i] + 1;
}
}
}
Your problem is due to sizeof(randArray). This method doesn't return the number of elements that are in the array.
For example:
int array[5] = { 1, 2, 3, 4, 5};
sizeof(array); // -> returns 20, because of 5 * 4 bytes (integer = 4 bytes)
Instead of using this method you should actually use the number of elements in the array. You declared the size of the array already in the beginning. So it is clear how many elements can be in the array.
Correct example:
int array[100] = {...};
for (int i = 0; i < 99; i++) {
for (int j = 0; j < 99; j++) {
if (array[i] == array[j]) {
// code for duplicates
}
}
}
#include <iostream>
#include <unistd.h>
#include <algorithm>
using namespace std;
int main()
{
int arr[8]={0,1,1};
int n = sizeof(arr) / sizeof(arr[0]);
cout<<n<<"\n";
/*Here we take two parameters, the beginning of the
array and the length n upto which we want the array to
be sorted*/
//sort(arr, arr + n);
for (int i=0;i<=n;i++){
cout<<arr[i]<<" ";
}
int result=0;
do{
for (int i=0;i<=n;i++){
for (int j =0;j<i;j++){
if(arr[j]==arr[i]){
srand(time(NULL)); // Seed the time
int finalNum = rand()%((10-1)+1); // Generate the number, assign to variable.
arr[i] = finalNum;
result = result + 1;
sleep(1);
i--;
}
}
}
}
while(result<=2);
n = sizeof(arr) / sizeof(arr[0]);
/*Here we take two parameters, the beginning of the
array and the length n upto which we want the array to
be sorted*/
//sort(arr, arr + n);
cout<<"\n";
for (int i=0;i<=n;i++){
cout<<arr[i]<<" ";
}
return 0;
}
(I'm assuming that randArray is a C-style array.) sizeof(randArray) does not return the number of elements in the array, it returns the number of bytes that randArray occupies.
Example (on wandbox):
int main()
{
int arr[] = {1, 2, 3, 4};
// Prints 16! (on my machine)
std::cout << sizeof(arr) << "\n";
}
The correct way of working with arrays in modern C++ is either using std::array or std::vector. They both provide a .size() method that returns the number of elements in the collection.
Your code is failing for these reasons:
sizeof does not return the number of elements in the array.
Incrementing a duplicate element by one does not guarantee that it will be unique.

Huge deletion error using C++ classes

I'm building an image analysing program in c++. It takes in a text file which holds the values to build a grey scale image. I am using the sum of squared differences to find a specific block in this image.. This is built using a matrix class in a header file so I have two overloaded constructors and a destructor which deletes the pointer to the double which allocates memory on the heap for this huge array of values (768 x 1024). This however throws out a memory error; Debug assertion failed, expression: block type is valid. I can't fathom why this is happening.. To do the SSD calculation I use two for loops; two matrix objects are manipulated one of these amendments calls one of the constructors to create a new matrix object from the getting a block from a larger matrix object. I understand that the destructor is called twice through every loop as the objects go out of scope? Is this double deletion and why the error occurs? Below are my constructors and the loops. If anyone can see why I'm getting this error I'd be very happy.
Constructors:
// Matrix constructor creating a new matrix object where all elements are the same number
Matrix::Matrix(int sizeR, int sizeC, double val)
{
//cout << "Matrix(int sizeR, int sizeC, double val) is invoked.." << endl;
M = sizeR;
N = sizeC;
data = new double[M * N];// Initialise space for class array 'data'
for (int i = 0; i < M* N; i++)
{
data[i] = val;// Set each element of the array to the same value passed to the constructor from main
}
}
// Matrix constructor taking pointer to array as input; creates a new matrix object
Matrix::Matrix(int sizeR, int sizeC, double* input_data)
{
//cout << "Matrix::Matrix(int sizeR, int sizeC, double* input_data) is invoked...." << endl;
M = sizeR;
N = sizeC;
data = new double[M * N];// Initialise space for class array 'data'
for (int i = 0; i < M * N; i++)
{
data[i] = input_data[i];// Set elements in data as elements from input_data passed to the constructor from main
}
}
Destructor:
// Matrix destructor
Matrix::~Matrix()
{
//cout << "Matrix::~Matrix() is invoked..." << endl;
delete data;
}
Code in main:
for (int i = 0; i < (768 - 21); i++)
{
for (int j = 0; j < (1024 - 21); j++)
{
counter++;
clutteredBlock = cluttered.getBlock(i, (i + 21), j, (j + 21));
diff = clutteredBlock - wallyBlock;
diff = diff * diff;
tempVal = diff.Sum();
if (i == 0 && j == 0)
{
ssd = tempVal;
}
if (tempVal <= ssd)
{
ssd = tempVal;
co1 = i;
co2 = j;
}
}
}
So M, N and data are all private class members; M and N are int and data is a double*; data being the pointer I'm trying to delete and getting nowhere with.
UPDATE: If I ignore the error I am then given a HEAP CORRUPTION error saying that I am trying to write to the heap after the buffer?
UPDATE: Assignment Operator;
Matrix& Matrix::operator=(const Matrix& input)
{
//cout << "Matrix::operator= is invoked..." << endl;
if (this == &input)
{
return *this;
}
else
{
delete data;
M = input.getR();
N = input.getC();
data = new double[M * N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
Set(i, j, input.Get(i, j));
}
}
}
return *this;
}
Any input is greatly appreciated :)
Use a std::vector for your storage. It handles allocation and deallocation automatically. Problem solved.