-7

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;
}
Sam
  • 939
  • 5
  • 14
  • 41
  • `**` is a pointer to a pointer, or in your case pointer to 2-D array. `double** filter_2d` means the return type of the function `filter_2d` is a pointer to a 2D double array. – Rohit Vipin Mathews Jun 16 '15 at 06:57
  • 1
    Please give a better way to find your problematic line than **Line 66**, I'm definitely not going to count the lines. :-/ – Rohit Vipin Mathews Jun 16 '15 at 06:59
  • 1
    Welcome to C++. Sweat buckets attempting to model a matrix as a `double**`. Realise why it's such a bad idea (jagged edge, memory allocated everywhere). Then bin the whole lot and use BLAS. www.boost.org. – Bathsheba Jun 16 '15 at 07:01
  • @Rohit: Line 65: double **filt_out = filter_2d(A, 3, 3, B, 2, 1); – Sam Jun 16 '15 at 07:02
  • possible duplicate of [conversion of 2D array to pointer-to-pointer](http://stackoverflow.com/questions/8203700/conversion-of-2d-array-to-pointer-to-pointer) – Rohit Vipin Mathews Jun 16 '15 at 07:18
  • 5
    **Read much more about [C++ programming](http://www.stroustrup.com/Programming/)**, then **use standard [containers](http://en.cppreference.com/w/cpp/container)** like [std::vector](http://www.cplusplus.com/reference/vector/vector/). – Basile Starynkevitch Jun 16 '15 at 07:18

8 Answers8

9

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];
3

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
}
Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
  • Thanks, that link helped me to correct the code. However, I still cannot see the output, do you have any idea? – Sam Jun 16 '15 at 07:42
  • @Sam - I have updated my answer to include that portion as well. – Rohit Vipin Mathews Jun 16 '15 at 09:24
  • Thanks, but I still get error and cannot compile it! – Sam Jun 16 '15 at 17:11
  • Can you add the error? Or try googling it. Filt_out is your offset and you need to add the indices to it to get the location of an item. Then doing ** would return you the contents of that location. – Rohit Vipin Mathews Jun 16 '15 at 17:44
  • here is the error: Access violation reading location 0xfdfdfdfd, I also think that the results are weird! because it should be somthing like this: 2 5 8 3 8 14 17 6 14 23 26 9 – Sam Jun 16 '15 at 18:13
  • Do you have any idea? – Sam Jun 17 '15 at 03:34
  • Should be the loop conditions. How do you assume the 5 and 4 that i and j iterates to? – Rohit Vipin Mathews Jun 17 '15 at 04:18
  • This function should do the convolution of A = [1 2 3; 4 5 6; 7 8 9] and B = [1 2], which will be [2 5 8 3; 8 14 17 6; 14 23 26 9]. However, I cannot get this output when I print the out of this function which is **filt_out – Sam Jun 17 '15 at 04:28
2

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.

Valy
  • 573
  • 2
  • 12
  • Thanks, I get this error: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(208): error C2440: 'initializing' : cannot convert from 'double *' to 'double'. There is no context in which this conversion is possible – Sam Jun 23 '15 at 17:07
  • What instruction is making that error show up? The program is working without problems on my computer. – Valy Jun 24 '15 at 13:09
  • I posted the error in my previous comment, does not it help? – Sam Jun 24 '15 at 16:33
  • @Sam Include stdlib.h in the code above to avoid the error. – Ely Jun 25 '15 at 06:16
1

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.

kfsone
  • 23,617
  • 2
  • 42
  • 74
1

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:

  1. 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.
  2. 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.

ManKeer
  • 543
  • 2
  • 6
  • 27
  • Thanks, your explanation was very useful I updated the code as you suggested, however, I think I am printing the wrong output, yes? I tried to print both *OutImage and OutImage and they are just some address – Sam Jun 21 '15 at 09:06
  • Would you please explain how you want to print the output ? to print the whole values in the output image, just use one loop start from 0 to 8. but you have to alter the pointer position each time, so after printing the value you need to add this line: OutImage++; – ManKeer Jun 21 '15 at 09:31
  • I want to print the output as a single column. As you said, I used this loop and again could not see the output and just see some address: for (int i = 0; i < 9; i++){ cout << OutImage[i] << endl; } – Sam Jun 21 '15 at 09:34
  • Inside your filter_2d function, you allocate this size (height_image + height_kernel - 1) for each row, this will produce a 9 * (height_image + height_kernel - 1) bytes in your array... To help you, please explain for me what you are looking to do exactly. – ManKeer Jun 21 '15 at 09:44
  • If the code works fine, I should get this output: 2 5 8 3 8 14 17 6 14 23 26 9 – Sam Jun 21 '15 at 17:12
  • What abot A_ptr and B_ptr, what are you going to fill these arrays, In case you just want to copy whatever in A and B, then it seems that you don't write the correct code. – ManKeer Jun 22 '15 at 07:30
  • A_ptr and B_ptr are my input data which are a large 2D matrix and a small 2D kernel, respectively. This is just a simple code for test – Sam Jun 22 '15 at 07:35
  • what are you going to fill both of them – ManKeer Jun 22 '15 at 07:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81154/discussion-between-sam-and-mankeer). – Sam Jun 22 '15 at 07:57
1

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.

Ely
  • 10,860
  • 4
  • 43
  • 64
  • Thanks Elyasin. I get this error: First-chance exception at 0x000000013fe0167f in mytry.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff. Unhandled exception at 0x000000013fe0167f in mytry.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff. The program '[14704] mytry.exe: Native' has exited with code -1073741819 (0xc0000005) – Sam Jun 25 '15 at 20:34
  • It happens in //print result – Sam Jun 25 '15 at 20:41
  • Can you give more details? Which OS, compiler, compiler options? Is that the only code you compile? Or do you embed it in another code? This code works for me on Ubuntu and Valy's code works for me also. I'd check your environment to be honest. – Ely Jun 25 '15 at 21:17
  • WIn 7, 64bit, msvc10. There is no other open program or code in my project. BTW, what is your mean by "Damn Sam, what were you thinking again?" ??!! – Sam Jun 25 '15 at 22:13
  • That was more of a joke. This means that the error is so obvious that you should not have committed it (again). You can ignore it. The important thing is that you understand the mistakes and the corrections. – Ely Jun 25 '15 at 22:30
  • Compiler options? IDE? – Ely Jun 26 '15 at 00:10
0

Yes, functions can returns pointers, or even pointers to pointers. I believe both of your answers are addressed by this thread.

Community
  • 1
  • 1
ross
  • 526
  • 5
  • 19
  • So, how should I call this function and print its output? I use double **filt_out = filter_2d(A, 3, 3, B, 2, 1); and msvc10 shows syntax error! – Sam Jun 16 '15 at 07:06
0
#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 ] );
}

 }
Vartika
  • 1,085
  • 3
  • 17
  • 43