Sunday, May 1, 2011

Pointer issue in C

Greetings, I am trying to learn pointers in C, I simply want my "addtwo" function to add 2 to every element of the input integer array, yet I get odd compilation errors, here is the non-pointer version which indeed won't properly compile.

addtwo(int *arr[]) {
    int i=0;
    for(;i< sizeof(arr)/sizeof(int);i++) {
        arr[i] = arr[i] + 2;
    }
}

main() {
    int myarray[] = {1,2,3,4};
    addtwo(myarray);
}

Regards

From stackoverflow
  • addtwo(int *arr[]) should be addtwo(int *arr)

    You cannot use sizeof to get the size of an array from a pointer. Typically you would either pass the size of the array as a separate arg or have some special value marking the last element.

    dirkgently : sizeof will not work within the body of addtwo. So not a complete answer.
  • Not to do with the compile error, but...

    You have to pass sizeof(arr) to the function instead of calling it in the function. When an array is passed to a function, C no longer sees it as an array, but as a single pointer to memory, so that sizeof(arr) as you are calling it now, will return the size of the pointer arr, which is most likely 4.

    Here's what I mean in code:

    void addtwo(int *arr, int size){
        int i=0;
        for(;i< size;i++){
            arr[i] = arr[i] + 2;
        }
    }
    
    int main(){
        int myarray[] = {1,2,3,4};
        addtwo(myarray, sizeof(arr)/sizeof(int));
        return 0; 
    }
    
    dirkgently : +1 It was correct initially. Post the edit, main is missing a return in the function signature line. The actual return 0; can be dropped though.
    DeadHead : sheesh... that was pretty bad of me to miss that... thanks
  • In C a notation int *arr[] is the same as int** arr.

  • You need to pass a pointer to the first element of the array and the array size. Array types decay to pointers in the context of function parameters. Try:

    void addtwo(int *arr, size_t size){
        for(size_t i = 0; i < size; i++){
            arr[i] = arr[i] + 2;
        }
    }
    
    
    int main() {
        int v[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
        addtwo(v, sizeof v / sizeof v[ 0 ]);
        return 0;
    }
    
  • You've some problems. First, you try to pass a int* to a parameter that's type int**. That won't work. Give it type int*:

    void addtwo(int *arr){
        int i=0;
        for(;i< sizeof(arr)/sizeof(int);i++){
            arr[i] = arr[i] + 2;
        }
    }
    

    Then, you need to pass the size in an additional argument. The problem is, that when you pass arrays, you really pass just a pointer (the compiler will make up a temporary pointer that points to the array's first element). So you need to keep track of the size yourself:

    void addtwo(int *arr, int size){
        int i=0;
        for(;i<size;i++){
            arr[i] = arr[i] + 2;
        }
    }
    
    
    int main(void) {
        int myarray[] = {1,2,3,4};
        addtwo(myarray, sizeof myarray / sizeof myarray[0]);
    }
    

    Now it will work. Also put the return type before them. Some compilers may reject your code, since it doesn't comply to the most recent C Standard anymore, and has long been deprecated (omitting the return type was the way you coded with the old K&R C).

    Adam Rosenfield : Alternatively, pass the array as an int[4] instead of int*.
    Johannes Schaub - litb : You cannot do that in C :( the best match for that would be to pass a pointer to the array. then it would look like void addtwo(int (*arr)[4]) ... addtwo(&myarray) . but you could not pass any other size, and it looks rather scary :)
    Johannes Schaub - litb : Have a look on this answer for details: http://stackoverflow.com/questions/779910/should-i-use-char-argv-or-char-argv-in-c/780147#780147
    Adam Rosenfield : Oops, you're right, although saying that you "cannot" do that isn't quite true -- you can still declare the parameter as int[4], but it's no different from int[] or int*.
    Johannes Schaub - litb : indeed :) i meant to say you cannot pass it as an int[4] . Of course nothing stops you from declaring the parameter as an int[4] :)
  • Though others already gave the correct response, basically you have an array of pointers when you have

    int *arr[]
    

    I doubt that is what you want. If you have

    int arr[]
    

    then that will also be equivalent to

    int *arr
    
  • addtwo argument declaration really reads:

    arr is an array of pointers to integer

    when you probably really want

    a pointer to an array of integers

    "How to Read C Declarations" has really helped me to grok the topic a while ago, maybe it will do the same for you.

0 comments:

Post a Comment