i have problem passing double pointer to my funciton
first i declare: int m, n; i read m and n from user just fine (i've checked that)
then i declere: int farm[m][n]; and i have a function... void harvest(int **farm,...); and when i call it with: harvest (farm,...); it says (compiler says):
cannot convert 'int (*)[((unsigned int)((int)n))]' to 'int**' for argument '1' to 'void harvest(int **,...)'

Recommended Answers

All 15 Replies

A two dimensional array is not the same type as a pointer to a pointer. If you want to pass a two dimensional array, change your function to accept the correct type. If you want to pass a pointer to a pointer then pass the correct type.

So what is it you really want to do? I can tell you that what you're doing is wrong all you want, or I can tell you how to accomplish your ultimate goal.

ok.....i new to these things...so i am making huge mistakes
i need to pass a two dim array...so how to pass it?
(btw can you tell how to pass a double pointer)

from what you said...it seems that double pointer is passed as int **
(is it the same as *int[])

thanks in advance

When you pass an array to a function you don't need to put in the [] brackets, unless your sending a multidimensional array (2D array) as your trying.

You should prototype your function like void harvest(int farm[m][n]...) and call it in your program like this harvest(farm...);

it doesnt seem to work...prototyping it with: void harvest (int farm[m][n],...); gives an error from compiler:
'm' was not declared in this scope
'n' was not declared in this scope
and few more errors...
i have even tried: void harvest (int farm[int m][int n],...); but then it says:
expected primary-expression before "int"
expected ']' before "int"
expected ',' or '...' before "int"
i have also tried: void harvest (int m, int n, int farm[m][n],...); but errors come up again:
'm' was not declared in this scope
'n' was not declared in this scope
and finally i have tried declaring m and n as global variables but then compiler says:
variable-sized type declared out of any function
i am new to this so i guess i am making stupid mistake
ill search on google about this more and if i find an answer ill post it myself
untill then...:)

>i am new to this so i guess i am making stupid mistake
It doesn't seem that way. If you were using a C99 compiler, it would work due to the new variable length array feature. However, unless you're able to compile as C99 (the latest standard) or your compiler supports an extension that allows variable length function parameters, you're stuck with the old fashioned method, which I assume is what you were trying to do originally:

#include <stdio.h>
#include <stdlib.h>

void foo ( int **p, int m, int n )
{
    int i, j;

    /*
      -Use- p just like an array, even though
      it's incompatible with array types
    */
    for ( i = 0; i < m; i++ ) {
        int j;

        for ( j = 0; j < n; j++ )
            printf ( "%4d", p[i][j] );
        putchar ( '\n' );
    }
}

int main ( void )
{
    int m = 4, n = 6;
    int **p;
    int i;

    /*
      Simulate an array of arrays so you can
      use normal array indexing syntax. There
      are other ways to avoid m+1 malloc calls,
      but this naive method is straightforward
      and easy to understand
    */
    p = malloc ( m * sizeof *p );

    for ( i = 0; i < m; i++ ) {
        int j;

        p[i] = malloc ( n * sizeof *p[i] );

        for ( j = 0; j < n; j++ )
            p[i][j] = i + j;
    }

    foo ( p, m, n );

    /* Don't forget to release the memory! */
    for ( i = 0; i < m; i++ )
        free ( p[i] );
    free ( p );

    return 0;
}

The down side to this method is that if you want to define the size of an "array" at runtime, you can't use an actual array. Instead, you have to simulate an array using dynamic memory, and this means you're stuck with all of the problems that dynamic memory shoves in your face.

i think i understand this method but im actually surprised that variable length feature doesnt work on my comp because im using minGW GCC that comes with newest version of CodeBlocks (28 Feb 2008).
> why i said im new to these things is mainly because i havent dealt with two dim arrays (and double pointers xd) being passed to function (- from here you can conclude that i didnt do serious programming in c, i had this type of problem before but i avoided it by choosing not to use functions, but now i need them because i need recursion)

i still think i am making mistake...correct me if im wrong but you said that i need to use:

#include <stdio.h>
#include <stdlib.h>

void harvest (int farm[a][b], int &pears, int *path, int x, int y);
/*
farm - farm where i store numbers of pears on each field...
pears - place where i store maximum number of pears collected so far
path - and a corresponding path to collect that amount of pears
x, y - coordinates of farmer collecting pears
*/

int main (void)
{
   int m, n;
    // Get m and n from user
   int farm[m][n];
   int path[m+n]; // Actually it is m + n - 2 because farmer never makes more steps that that
   int pears = 0;
   int x=0, y=0;
   
    // Read values for each cell from file (i've checked that and input is ok)
   harvest (farm, pears, path, x, y);
}

void harvest (int farm[a][b], int &pears, int *path, int x, int y);
{
// Here comes some code for function, algorithm (kind of) so i dont think it's important
}

maybe i said unimportant things but im just saying them so you can get the idea of what am i trying to do (and correct again if im wrong)

>im using minGW GCC that comes with newest version of CodeBlocks
You have to turn C99 mode on with a switch: -std=c99.

>correct me if im wrong but you said that i need to use:
Did you completely ignore everything I said? Also, by the looks of your code you're not even using C89, much less C99. You're using C++, which doesn't support runtime sized arrays in any way, shape, or form.

i didn ignore...im just trying to figure the other way suggested by kenji (easier one XD)

now im puzzled, maybe because in school i learn c and c++, their combination actually, so i dont know what is native to each language...
1. can i declare variables and arrays wherever in my program (as long as i use them in same or inner scopes and after declaration)? (any difference c, c++?)
2. passing a value by reference and passing a pointer to a value only differ in way of accessing that variables value?
3. do i pass arrays to functions by passing a pointer to first element of array (1 dim arrays)
4. argv...is it double pointer, or it is name of 2 dim array
...i think that should be enough questions....if i understand half of answers to questions i gave...it will be great

one more...what are differences if i enable c99?

>im just trying to figure the other way suggested by kenji (easier one XD)
Did I miss something, or haven't you already tried every variation of kenji's suggestion and none of them worked? If you're hell bent on following a path that isn't going to work, let me know now so I can help other people and leave you to your willful ignorance.

>1. can i declare variables and arrays wherever in my program (as
>long as i use them in same or inner scopes and after declaration)?
>(any difference c, c++?)
C89: All variables must be declared at the beginning of a block.
C99/C++: You can declare a variable anywhere you want as long as you declare it before it's used.

>2. passing a value by reference and passing a pointer to a value
>only differ in way of accessing that variables value?
C doesn't support pass by reference at all.

>3. do i pass arrays to functions by passing a pointer to first
>element of array (1 dim arrays)
Yes.

>4. argv...is it double pointer, or it is name of 2 dim array
argv is pointer to a pointer.

>what are differences if i enable c99?
The ones you'll probably care about the most are the following:

  • // comments are now standard conforming.
  • Variables don't have to be at the beginning of a block.
  • You can declare a for loop variable as part of the loop:
    for ( int i = 0; i < n; i++ ) {
      ...
    }
  • _Bool is a supported type, which a bool macro.
  • long long is a supported type.

heh...i found this:
http://gcc.gnu.org/c99status.html
looks like i cannot declare variable-length arrays and this is one of the things i had no clue about
thanks again for all spent time and given advice
what IDE do you suggest using
or better, what compiler and debugger

>looks like i cannot declare variable-length arrays
They're implemented, just not to the letter of the rules in the C99 standard.

>what IDE do you suggest using
>or better, what compiler and debugger
Try out as many as you can and decide that for yourself. Choice of compiler/debugger/IDE is very personal, and these days the most common ones are all equally high quality.

yeah....im asking because im still in process of extensive learning and everything compiler specific that i hear is bad.
i will stick to old fashioned method (it seems that i had to cast malloc to matching type but it works great thanks)
i have tried to find on google but failed - how do i enable compiler flags, there are some that are built in and i can enable using checkbox on compiler settings but cant find the right place to enable that -std=C99 flag...
what compiler are you using (if yours can compile this)
(just to make sure i get that old fashioned method): p = malloc(m * sizeof *p); that sizeof *p evaluates to size of pointer to pointer
and in: p[i] = malloc(m * sizeof *p[i]); sizeof *p evaluates to size of pointer?

>i dont want to think that things such as void main() are as good as int main() etc.
There's no such thing as an absolute. Even if you say that int main is better than void main, you'd be wrong. In freestanding implementations, void main is usually preferable to int main, and still conforms perfectly to the standard. Now, there are two ways you would have learned that if I hadn't told you:

  1. You filled your head with pointless trivia in the "process of extensive learning". You might even have remembered that particular tidbit of information at the crucial time when it was needed.
  2. You tried to correct someone who knew the rules and learned from the mistake. The pain of making a mistake is by far the best way to engrave knowledge into your brain.

My point is that being book smart doesn't buy you as much as you'd think. Knowing how to write perfect code in theory won't save you when you run into real world problems that theory doesn't mention. The best way to learn is to get down in the mud and learn the hard way. Even if you learn bad habits, it all corrects itself eventually if you do it long enough.

Remember that experience (ie. practice!) is your foundation, and you supplement it with things like rules and standards.

>i have actually just found -pedantic compiler flag (strict ISO C/C++)
-Wall, -ansi, and -pedantic are your friends.

>problem i am facing at the moment is where do i actually enable flags
You're using Code::Blocks, so there should be compiler options somewhere in the project settings. With GCC I believe there's even a friendly bunch of check boxes that give you what you want without having to know or type the switches themselves.

while you was posting last one i edited previous post - sorry
i wrote whole bunch of unnecessary things in first version of post

>it seems that i had to cast malloc to matching type but it works great thanks
That's because you're not compiling as C, you're compiling as C++.

>cant find the right place to enable that -std=C99 flag...
IIRC (though I haven't used Code::Blocks for a few revisions), there's an advanced options box where you can type out the switches just like you would on the command line. It's somewhere in the compiler options as well.

>what compiler are you using (if yours can compile this)
If by "this" you mean the code I posted, then I used Visual Studio to compile it. However, it's standard C89, so there shouldn't be any problems with any conforming C compiler.

>p = malloc(m * sizeof *p); that sizeof *p evaluates to size of pointer to pointer
Correct. Note (because this can be confusing) that it's safe to dereference an uninitialized pointer in the sizeof expression because the expression is not evaluated. All it does is calculate the size of the resulting type in bytes.

>p = malloc(m * sizeof *p); sizeof *p evaluates to size of pointer?
Correct.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.