C++ Program producing false result... What is the cause? - c++

Something is wrong with this code as it modifies an array. All elements are assigned 0. But why ?? Here's the question of program:
Write a function named "subtotal" takes as its arguments the following:
(1) an array of floating point values;
(2) an integer that tells the number of cells in the array.
The function should replace the contents of each cell with the sum of the contents of all the cells in the
original array from the left end to the cell in question.
Thus, for example, if the array passed to the
function looks like this:
[0] [1] [2] [3] [4]
5.8 | 2.6 | 9.1 | 3.4 | 7.0
then when the function returns, the array will have been changed so that it looks like this:
[0] [1] [2] [3] [4]
5.8 | 8.4 | 17.5 | 20.9 | 27.9
because 5.8 + 2.6 = 8.4 and 5.8 + 2.6 + 9.1 = 17.5 and so on. Note that the contents of cell [0] are not
changed. The function should not return a value.
And here is the program which I've made:
#include<iostream>
using namespace std;
void subtotal(float*,int);
int main(void)
{
int n;
cout << "Enter the number of cells: ";
cin >> n;
float* cell;
cell = new float[n];
cout << "Enter the elements: ";
for(int i = 0; i < n; i++)
cin >> *(cell + i);
subtotal(cell, n);
for(int i = 0; i < n; i++)
cout << *(cell + i) << "|";
delete[] cell;
}
void subtotal(float* cell, int n)
{
int i, j;
for(i = 0; i < n; i++)
{
float sum = 0;
for(j = 0; j < i; j++)
{
sum += *(cell + j);
}
*(cell + i) = sum;
}
}

Why using nested loop? You can use only one loop so that the you'll iterate once is enough as long as you want only sum the consecutive elements so change the function subtotal to:
void subtotal(float* cell, int n)
{
for(int i = 0; i < n - 1; i++) // `n - 1` to avoid outband
{
float sum = cell[i] + cell[i + 1];
cell[i + 1] = sum;
}
}
Or if you want to do it using pointer like in your case:
void subtotal(float* cell, int n)
{
for(int i(0); i < n - 1; i++)
{
float sum = *(cell + i) + *(cell + i + 1);
*(cell + i + 1) = sum;
}
}

You should do j <= i in the inner loop. If you don't do that, the first new element in the array will be zero (summing over no elements at all). For the second element, it will only sum over the first, which is 0 again. Etc.
In addition, your code is very non-idiomatic. The normal way to address an array element is cell[i], not *(cell+i), although both ways are possible for plain arrays.

This is how your code should be:
#include<iostream>
using namespace std;
void subtotal(float*,int);
int main(void)
{
int n = 5;
float *cell=new float[n];
cell[0] = 5.8f;
cell[1] = 2.6f;
cell[2] = 9.1f;
cell[3] = 3.4f;
cell[4] = 7.0f;
subtotal(cell,n);
for(int i=0;i<n;i++)
cout<<*(cell+i)<<"|";
delete []cell;
}
void subtotal(float*cell,int n)
{
float * temp = new float [n];
int i,j;
for(i=0;i<n;i++)
{
float sum=0;
for(j=0;j<=i;j++) // Change here
{
sum+=*(cell+j);
}
*(temp+i)=sum; // Change here
}
for (int i =0; i < n; ++i) {
cell[i] = temp[i]; // Copy the values back
}
delete [] temp;
}
There are two problems with your subtotal function.
First, you should do j <= i in the inner loop.
Next, you should store the summation in a temporary array, else you are going to make changes to the original input after each subset sum and the output you will get will not be the desired one. You would have got output like this :
5.8|8.4|23.3|40.9|85.4|
However, with the changes I have proposed, you should get the desired output:
5.8|8.4|17.5|20.9|27.9|
corrected-code-here

Related

How to insert product and sum between every two consecutive elements in an array

In a vector, I must insert product and sum between every two consecutive elements.For example the
1 2 3 4 vector will become 1 3 2 2 5 6 3 7 12 4.
This is the code i did till now.
You can see that the function which makes the insertion is insertInVector().
#include <iostream>
void sumProduct(int a, int b, int* suma_functie, int* produs_functie)
{
*suma_functie = a + b;
*produs_functie = a * b;
}
void insertInVector(int &n,int v[])
{
int suma, produs;
for (int i = 1; i <= n; i++)
{
sumProduct(v[i], v[i + 1], &suma, &produs);
v[i + 4] = v[i + 1];
v[i + 1] = suma;
v[i + 5] = v[i + 2];
v[i + 2] =produs ;
}
}
void readVector(int n, int v[])
{
for (int i = 1; i <= n; i++)
std::cin >> v[i];
}
void displayVector(int& n, int v[])
{
for (int i = 1; i <= n; i++)
std::cout << v[i]<<" ";
}
int main()
{
int n,v[100];
std::cin >> n;
readVector(n, v);
insertInVector(n, v);
displayVector(n, v);
}
I changed some things in your code. One of the main things is that you can't insert in the middle of an array as it has a static memory (if you want to change only in the given array without using anything extra then you should use vector instead of array). So for this purpose, I have used an extra temp array and reflected those changes in the original array at the end. Also, I used pass by reference in the function sumProduct as I am not aware of the way you were using it; you can change it if you want. Also n+(2*(n-1)) is the new length of the array which can easily be predicted from the question. Just check out the changes in insertInVector function you will understand the rest.
#include <iostream>
void sumProduct(int a, int b, int& suma_functie, int& produs_functie)
{
suma_functie = a + b;
produs_functie = a * b;
}
void insertInVector(int &n,int v[])
{
int suma, produs;
int temp[100];
for (int i = 1, j=1; i <= n-1; i++)
{
temp[j]=v[i];
sumProduct(v[i], v[i + 1], suma, produs);
temp[j+1]=suma;
temp[j+2]=produs;
j+=3;
}
int n2=n;
n=n+(2*(n-1));
temp[n]=v[n2];
for (int i=1; i<= n; i++)
{
v[i]=temp[i];
}
}
void readVector(int n, int v[])
{
for (int i = 1; i <= n; i++)
std::cin >> v[i];
}
void displayVector(int& n, int v[])
{
for (int i = 1; i <= n; i++)
std::cout << v[i]<<" ";
}
int main()
{
int n,v[100];
std::cin >> n;
readVector(n, v);
insertInVector(n, v);
displayVector(n, v);
}
Hope it helps!
User8411584 is completely correct in pointing out that you need to create a temporary copy of the array first instead of simply beginning to overwrite it.
Just a little addition though:
The term for the new length of the resulting array n+(2*(n-1)) can be simplified to 3n-2.

Getting a weird negative number in my output when using an array I modified in one function, in another function

I am writing a program that takes a user-inputted list of up to 25 integers, then prints the sorted list using bubble sorting, the sorted list in descending order, and some other info about the list like the median, minimum and maximum, and mode.
I have tested all of my functions within the program individually on an array I created using initializer lists (not from user input/cin) and they work fine, but when I run the program something is off. For example, when I input 1,2,3,4, the function that prints the sorted list in descending order prints 3,2,1, -858993460. It always leaves out the greatest integer and adds on -858993460 at the end no matter what values I put into the input array. Here's the relevant part of my code:
#include <iostream>
using namespace std;
void input(int ulist[26], int& n);
void Bubblesort(int ulist[26], int slist[26], int n);
void print(int list[26], int n);
int n;
void reversesort(int slist[26], int n);
void main()
{
int ulist[26], slist[26];
input(ulist, n);
cout << "Unsorted";
print(ulist, n);
cout << "Sorted";
Bubblesort(ulist, slist, n);
print(slist, n);
reversesort(slist, n);
cin >> n;
}
void input(int ulist[26], int& n)
{
int i(0), value;
cout << "enter value : \n";
cin >> value;
while (i < 25 && value != -999)
{
ulist[i] = value;
i++;
if (i < 25)
{
cin >> value;
}
}
n = i;
}
void Bubblesort(int ulist[26], int slist[26], int n)
{
int i, j, temp;
for (i = 0; i < n; i++)
slist[i] = ulist[i];
for (j = 25 - 1; j > 0; j--) //25 is Length of the array
for (i = 0; i < j; i++)
if (slist[i] > slist[i + 1])
{
temp = slist[i];
slist[i] = slist[i + 1];
slist[i + 1] = temp;
}
}
void print(int list[26], int n)
{
int i;
cout << " list of numbers are : \n";
for (i = 0; i < n; ++i)
{
cout << list[i] << '\n';
}
cout << "\n\n";
}
void reversesort(int slist[26], int n) //checked w online compiler, works
{
cout << "List of numbers in descending order is: \n";
for (int i = n - 1; i >= 0; --i)
cout << slist[i] << ", ";
cout << "\n";
}
I'm assuming this is some sort of memory problem and that the source of this has to do with passing slist, which was modified in the bubblesort function, through the functions I wrote. I'm pretty new to C++ (coming from python) so I'm assuming I'm missing something as far as passing arrays to functions is concerned.
EDIT: I guess to sum everything up - how can I take the data inputted in the input function and use that array in another function? And how can I take the array that has been sorted by the bubblesort function and use that array in another function?
The first instance of undefined behavior in your code is
if (slist[i] > slist[i + 1])
in Bubblesort.
Due to
for (j = 25 - 1; j > 0; j--)
for (i = 0; i < j; i++)
the maximum index accessed by this loop is slist[24] (24 from i + 1 where i < j and j = 25 - 1 = 24, so i = 23).
Your input is only 4 numbers, so only slist[0] through slist[3] are initialized. The remaining elements (slist[4] through slist[25]) are uninitialized. Reading from an uninitialized variable has undefined behavior.

Calling a pointer function in 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 ] );
}
}

Prime Factoring, no IO

Dear StackOverflow community,
I am trying to write code that accepts a "primefactorized" array, each element originally describing their final multiplicational product.
The code I'm trying to write then reads this array and turns it to the exponentiation of prime numbers, each index of the array corresponding to the next prime number, and each element on the index the power to which it must be raised. I believe I have done so, but I cannot for some reason get my IO working. For some reason when I switched the inner for-loops last incrementation part to an "i++" instead of the correct "j++", it would display the loop.
Relevant snippet
// Next stage: Take the array and turn in into the form described earlier
for(unsigned int i = 0; i < sizeof(result); i++)
{
temppower = result[i];
tempcounter = 1; // counter to control the loop.
for(unsigned int j = 0; i < sizeof(result)-1; j++)
{
if(result[j]+1 == temppower)
{
tempcounter++;
result[j+1] = 0;
}
}
result[i] = tempcounter;
}
for(unsigned int i = 0; i < sizeof(result); i++)
{
cout << result[i] << " ";
}
cout << endl;
Full code
#include <iostream>
#include <cmath>
#include <climits>
using namespace std;
#include "fact.h"
/** eartosthenes constructs an up-to-n primes array of length len .
* #param n call-by-value, top value for construction of primes.
* #param &len call-by-reference, the finished size of the array of primes.
* #return int* pointer to the first element of the array of primes.
* Description:
* The eartosthenes method of calculating primes are efficient for relative low primes (up to 10 million or so).
* You can read about the method at http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
* You can use wolfram-alpha https://www.wolframalpha.com/ and run Prime(start)...Prime(end) to get the primes
* between start and end, e.g. Prime(1)...Prime(10) yield {2,3,5,7,11,13,17,19,23,29}.
*/
int * eratosthenes(int n, int & len){
// computes all prime numbers up to n
// returns the prime numbers as an array
// the len parameter will be set to the length of the array
bool *isPrime=new bool [n+1]; // construct [n+1] booleans
len=0;
// initialize every value from 1..n to true.
for(int i=2; i<=n; i++){
isPrime[i]=true;
}
// now we'll start at 2, and for every number of multiplicity 2.
// e.g. 2*{1,2,3,4...n} is then set to false, as they are dividable by 2.
// then we increment to 3, during the same.
for(int i=2; i<=n; i++){
if(isPrime[i]){
len++; // for each such iteration, we increase our desired length.
for(int j=2*i; j<=n; j+=i){
isPrime[j]=false; // set every(n) multiplicity of 2 to false.
}
}
}
// having used erathosthenes formula, we now construct our array.
int *result=new int[len];
// now we need to return the primes-filled array.
for(int i=0, j=2; i<len; i++){
// if it's not a prime, then we spin the value up.
while(!isPrime[j]) j++;
// when the while-loop no longer hold, we'll have the iterations desired prime
// we then set it, and the for-loop will continue to the next.
result[i]=j++;
}
delete [] isPrime; // always delete what you have allocated with new.
// we say these allocation are on the heap or free store (c-syntax)
return result;
}
#include "fact.h"
factrep new_factrep()
{
factrep result;
result = new int[len];
return result;
}
factrep primfact(int n)
{
factrep result;
result = new int[len];
int m; // still to factorize number
int f; // current factor
int index = 0; // index of factrep array
int temppower = 0; // index for the power
int tempcounter = 0; // counter to help the power determine its size
m=n;
f=2;
// 0-initialize the result array
for(unsigned int i = 0; i < sizeof(result); i++)
{
result[i] = 0;
}
// continue until nothing to factorize
while(m != 1){
// while the factor divides m, go on
while(m % f == 0){
if(m!=1)
{
m=m/f;
result[index] = f;
index++;
}
else
{
result[index] = f;
break;
}
}
// increment factor
f++;
}
// Next stage: Take the array and turn in into the form described within
// the exercise handout,
for(unsigned int i = 0; i < sizeof(result); i++)
{
temppower = result[i];
tempcounter = 1; // counter to control the loop.
for(unsigned int j = 0; i < sizeof(result)-1; j++)
{
if(result[j]+1 == temppower)
{
tempcounter++;
result[j+1] = 0;
}
}
result[i] = tempcounter;
}
for(unsigned int i = 0; i < sizeof(result); i++)
{
cout << result[i] << " ";
}
cout << endl;
return result;
}
factrep mult(factrep f1, factrep f2)
{
factrep result;
result = new int[len];
for(int i = 0; i < len; i++)
{
result[i] = f1[i]+f2[i];
}
return result;
}
int getint(factrep f)
{
int result = 0;
// int *temparray = new int[len];
for(int i = 0; i < len; i++)
{
result *= pow(primes[i],f[i]);
}
return result;
}
// these are our global variables
// so in our header we called extern
// which basically tells c++, that we'll define them in another file.
int *primes;
int len;
int main(){
// construct our primes array with maximum integer value
primes=eratosthenes(sqrt(INT_MAX),len);
// len now contains the length of the primes.
// TEST VALUES
// these are our test values.
int n=60;
int m=25;
int l=640;
// first check for non-negative content
if ( n < 0 || m < 0 || l < 0){
cout << "values must be positive (n > 0)" << endl;
return 1;
}
// construct 3 prime-factorized arrays by the values (60,25,640)
factrep fn=primfact(n);
factrep fm=primfact(m);
factrep fl=primfact(l);
// Verify that these are indeed constructed with those values
cout << getint(fn) << " " << getint(fm) << " " << getint(fl) << endl;
// multiply: fn = fn*fm, fm = fl*fl, fl = fn*fm
// 1500 = 60*25, 409600 = 640*640, 614400000 = 1500*409600
fn=mult(fn,fm);
fm=mult(fl,fl);
fl=mult(fn,fm);
// Verify that our functions work as expected by printing out their values now.
cout << getint(fn) << " " << getint(fm) << " " << getint(fl) << endl;
/* Expected output:
60 25 640
1500 409600 614400000
*/
// and again, if we construct something on the heap/free-store we better delete it again
// otherwise we might have a memory-leak on our hands.
delete [] primes;
delete [] fn;
delete [] fm;
delete [] fl;
return 0;
}
Update
The error was pointed out to me: I had put an i variable reference within the inner-most loop instead of the j variable I was using. (facepalm).
In the meantime this realization quickly helped me to solve my original problem which I will paste below in case anyone might run into a similar problem (primes[] is an array of primes, one per element, established outside of the factrep functions)
for(unsigned int i = 0; i < sizeof(result); i++)
{
temppower = primes[i];
tempcounter = 0; // counter to control the loop.
for(unsigned int j = 0; j < sizeof(result); j++)
{
if(result[j] == temppower)
{
tempcounter++;
}
}
result[i] = tempcounter;
}
Line 116 : A loop is endless.
for(unsigned int j = 0; i < sizeof(result)-1; j++)
i never changes in the inner loop where j is increasing, thus preventing your program from advancing further and printing anything.

Sorting an array diagonally

I've looked up some websites but I couldn't find an answer to my problem.
Here's my code:
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
#include<iomanip>
#include<array>
#include <algorithm>
using namespace std;
const int AS = 6;
int filling(void);
void printing(int[AS][AS]);
int forsorting(int[][AS], int);
int main()
{
int funny = 0;
int timpa = 0;
int counter = 0;
int Array[AS][AS];
srand(time(0));
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
Array[i][j] = filling();
}
cout << "The unsorted array is" << endl << endl;
printing(Array);
cout << "The sorted array is" << endl << endl;
for (int il = 0; il<AS; il++)
{
for (int elle = 0; elle<AS; elle++)
Array[il][elle] =forsorting(Array, funny);
printing(Array);
}
system("PAUSE");
return 0;
}
int filling(void)
{
int kira;
kira = rand() % 87 + 12;
return kira;
}
void printing(int Array[AS][AS])
{
int counter = 0;
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
{
cout << setw(5) << Array[i][j];
counter++;
if (counter%AS == 0)
cout << endl << endl;
}
}
}
int forsorting(int Array[AS][AS], int funny)
{
int c, tmp, x;
int dice = 0;
int Brray[AS*AS];
int timpa = 0;
int super = 0;
//Transofrming Array[][] into Brray[]
for (int i = 0; i < AS; i++)
{
for (int k = 0; k < AS; k++)
{
Brray[timpa] = Array[i][k];
timpa++;
}
}
//Bubble sorting in Brray[]
for (int passer = 1; passer <= AS-1; passer++)
{
for (int timon = 1; timon <= AS-1; timon++)
{
if (Brray[timpa]>Brray[timpa + 1])
{
super = Brray[timpa];
Brray[timpa] = Brray[timpa + 1];
Brray[timpa + 1] = super;
}
}
}
//Transforming Brray[] into Array[][]
for (int e = 0; e<AS; e++)
{
for (int d = 0; d<AS; d++)
{
Brray[dice] = Array[e][d];
dice++;
}
}
***There's a part missing here***
}
What I have to do is, write a program using 3 functions.
The 1st function would fill my 2D array randomly (no problem with this part)
the 2nd function would print the unsorted array on the screen (no problem with this part)
and the 3rd function would sort my array diagonally as shown in this picture:
Then I need to call the 2nd function to print the sorted array. My problem is with the 3rd function I turned my 2D array into a 1D array and sorted it using Bubble sorting, but what I can't do is turn it back into a 2D array diagonaly sorted.
If you can convert from a 2D array to a 1D array, then converting back is the reverse process. Take the same loop and change around the assignment.
However in your case the conversion itself is wrong. It should take indexes in the order (0;0), (0;1), (1;0). But what it does is take indexes in the order (0;0), (0;1), (1;1).
My suggestion is to use the fact that the sum of the X and Y coordinates on each diagonal is the same and it goes from 0 to AS*2-2.
Then with another loop you can check for all possible valid x/y combinations. Something like this:
for ( int sum = 0; sum < AS*2-1; sum++ )
{
for ( int y = sum >= AS ? sum-AS+1 : 0; y < AS; y++ )
{
x = sum - y;
// Here assign either from Array to Brray or from Brray to Array
}
}
P.S. If you want to be really clever, I'm pretty sure that you can make a mathematical (non-iterative) function that converts from the index in Brray to an index-pair in Array, and vice-versa. Then you can apply the bubble-sort in place. But that's a bit more tricky than I'm willing to figure out right now. You might get extra credit for that though.
P.P.S. Realization next morning: you can use this approach to implement the bubble sort directly in the 2D array. No need for copying. Think of it this way: If you know a pair of (x;y) coordinates, you can easily figure out the next (x;y) coordinate on the list. So you can move forwards through the array from any point. That is all the the bubble sort needs anyway.
Suppose you have a 0-based 1-dimensional array A of n = m^2 elements. I'm going to tell you how to get an index into A, given and a pair of indices into a 2D array, according to your diagonalization method. I'll call i the (0-based) index in A, and x and y the (0-based) indices in the 2D array.
First, let's suppose we know x and y. All of the entries in the diagonal containing (x,y) have the same sum of their coordinates. Let sum = x + y. Before you got to the diagonal containing this entry, you iterated through sum earlier diagonals (check that this is right, due to zero-based indexing). The diagonal having sum k has a total of k + 1 entries. So, before getting to this diagonal, you iterated through 1 + 2 + ... + (sum - 1) entries. There is a formula for a sum of the form 1 + 2 + ... + N, namely N * (N + 1) / 2. So, before getting to this diagonal, you iterated through (sum - 1) * sum / 2 entries.
Now, before getting to the entry at (x,y), you went through a few entries in this very diagonal, didn't you? How many? Why, it's exactly y! You start at the top entry and go down one at a time. So, the entry at (x,y) is the ((sum - 1) * sum / 2 + y + 1)th entry, but the array is zero-based too, so we need to subtract one. So, we get the formula:
i = (sum - 1) * sum / 2 + y = (x + y - 1) * (x + y) / 2 + y
To go backward, we want to start with i, and figure out the (x,y) pair in the 2D array where the element A[i] goes. Because we are solving for two variables (x and y) starting with one (just i) and a constraint, it is trickier to write down a closed formula. In fact I'm not convinced that a closed form is possible, and certainly not without some floors, etc. I began trying to find one and gave up! Good luck!
It's probably correct and easier to just generate the (x,y) pairs iteratively as you increment i, keeping in mind that the sums of coordinate pairs are constant within one of your diagonals.
Store the "diagonally sorted" numbers into an array and use this to display your sorted array. For ease, assume 0-based indexing:
char order[] = { 0, 1, 3, 6, 10, 2, 4, 7, 11, 15, .. (etc)
Then loop over this array and display as
printf ("%d", Array[order[x]]);
Note that it is easier if your sorted Array is still one-dimensional at this step. You'd add the second dimension only when printing.
Following may help you:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>
template<typename T>
class DiagArray
{
public:
DiagArray(int size) : width(size), data(size * size), orders(size * size)
{
buildTableOrder(size);
}
const T& operator() (int x, int y) const { return data[orders[width * y + x]]; }
T& operator() (int x, int y) { return data[orders[width * y + x]]; }
void sort() { std::sort(data.begin(), data.end()); }
void display() const {
int counter = 0;
for (auto index : orders) {
std::cout << std::setw(5) << data[index];
counter++;
if (counter % width == 0) {
std::cout << std::endl;
}
}
}
private:
void buildTableOrder(int size)
{
int diag = 0;
int x = 0;
int y = 0;
for (int i = 0; i != size * size; ++i) {
orders[y * size + x] = i;
++y;
--x;
if (x < 0 || y >= size) {
++diag;
x = std::min(diag, size - 1);
y = diag - x;
}
}
}
private:
int width;
std::vector<T> data;
std::vector<int> orders;
};
int main(int argc, char *argv[])
{
const int size = 5;
DiagArray<int> da(size);
for (int y = 0; y != size; ++y) {
for (int x = 0; x != size; ++x) {
da(x, y) = size * y + x;
}
}
da.display();
std::cout << std::endl;
da.sort();
da.display();
return 0;
}
Thank you for your assistance everyone, what you said was very useful to me. I actually was able to think about clearly and came up with a way to start filling the array based on your recommendation, but one problem now, Im pretty sure that my logic is 99% right but there's a flaw somewhere. After I run my code the 2nd array isnt printed on the screen. Any help with this?
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
#include<iomanip>
#include<array>
#include <algorithm>
using namespace std;
const int AS = 5;
int filling(void);
void printing(int[AS][AS]);
int forsorting(int[][AS], int);
int main()
{
int funny = 0;
int timpa = 0;
int counter = 0;
int Array[AS][AS];
srand(time(0));
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
Array[i][j] = filling();
}
cout << "The unsorted array is" << endl << endl;
printing(Array);
cout << "The sorted array is" << endl << endl;
for (int il = 0; il<AS; il++)
{
for (int elle = 0; elle<AS; elle++)
Array[il][elle] =forsorting(Array, funny);
}
printing(Array);
system("PAUSE");
return 0;
}
int filling(void)
{
int kira;
kira = rand() % 87 + 12;
return kira;
}
void printing(int Array[AS][AS])
{
int counter = 0;
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
{
cout << setw(5) << Array[i][j];
counter++;
if (counter%AS == 0)
cout << endl << endl;
}
}
}
int forsorting(int Array[AS][AS], int funny)
{int n;
int real;
int dice = 0;
int Brray[AS*AS];
int timpa = 0;
int super = 0;
int median;
int row=0;
int col=AS-1;
//Transofrming Array[][] into Brray[]
for (int i = 0; i < AS; i++)
{
for (int k = 0; k < AS; k++)
{
Brray[timpa] = Array[i][k];
timpa++;
}
}
//Bubble sorting in Brray[]
for (int passer = 1; passer <= AS-1; passer++)
{
for (int timon = 1; timon <= AS-1; timon++)
{
if (Brray[timpa]>Brray[timpa + 1])
{
super = Brray[timpa];
Brray[timpa] = Brray[timpa + 1];
Brray[timpa + 1] = super;
}
}
}
//Transforming Brray[] into sorted Array[][]
for(int e=4;e>=0;e--)//e is the index of the diagonal we're working in
{
if(AS%2==0)
{median=0.5*(Brray[AS*AS/2]+Brray[AS*AS/2-1]);
//We start filling at median - Brray[AS*AS/2-1]
while(row<5 && col>=0)
{real=median-Brray[AS*AS/2-1];
Array[row][col]=Brray[real];
real++;
col--;
row++;}
}
else {
median=Brray[AS*AS/2];
//We start filling at Brray[AS*AS/2-AS/2]
while(row<5 && col>=0)
{real=Brray[AS*AS/2-AS/2];
n=Array[row][col]=Brray[real];
real++;
col--;
row++;}
}
}
return n;
}
Thanks again for your assistance