1
#include <stdio.h>

void spiral(int a[10][10]) {
    printf("%d", a[1][3]);
}

int main() {
    int r, c, j, i;
    scanf("%d%d", &r, &c);
    int a[r][c];
    for (i = 0; i < r; i++)
        for (j = 0; j < c; j++) {
            scanf("%d", &a[i][j]);
        }

    spiral(a);
    return 0;
}

When I give a 3 x 6 array

 1   2   3   4   5   6
 7   8   9  10  11  12
13  14  15  16  17  18

The output is 14, while it should be 10

How to fix this issue?

2
  • how can i set the size of spiral array before running the program? any idea? Commented Feb 6, 2016 at 18:21
  • "Why does my program give wrong results if I specify wrong dimensions for an array to my function? Did you try with an array with the both dimensions 10? (or at least the inner dim) Commented Feb 6, 2016 at 18:50

2 Answers 2

3

If you enter 3 and 6 for r and c (respectively) then the type of a is not int[10][10] (or int(*)[10] as the spiral argument really is), it's int[3][6]. The memory layout is completely different for the arrays, leading to undefined behavior.

You can solve this by passing the size along to the function, and using it in the declaration of the array:

void spiral(const size_t r, const size_t c, int (*a)[c]) { ... }

Call it like expected:

spiral(r, c, a);

As noted using int a[r][c] as argument might be easier to read and understand, but it gives a false impression that a is actually an array. It's not. The compiler treats the argument as a pointer to an array of c integers, i.e. int (*a)[c].

This makes me a little conflicted... On the one hand I'm all for making things easier to read and understand (which means it will be easier to maintain), on the other hand newbies often get it wrong and think that one can pass an array intact when in fact it decays to a pointer which can lead to misunderstandings.

Sign up to request clarification or add additional context in comments.

2 Comments

I think you missed something in the parameter-list. And I wonder why you not just use int a[r][c]. Technically the same, but imo better for documentation purposes.
void spiral(int r, int c, int a[r][c]) { ... } is a simpler prototype that fits the purpose. Note that modifying r or c in the body of spiral would have no effect on the structure of a nor on accessing its elements, and a is not guaranteed to have r rows, a is really a pointer in the function: sizeof(a) == sizeof(int*)
0

A few things are wrong: in void spiral() you ask for a 2D-array of 10*10, but you do not give that. Keep that part as a variable, so only ask the type you receive and not what you want to receive and with creating a dynamic array you should always do that with malloc or calloc and free them afterwards. This might be a bit hard at first, but when you start creating bigger programs this is a must if you have a question or do not understand the pointers in the program called (*) then ask me:

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

void spiral(int **a) {
    printf("%d", a[1][3]);
}

int main() {
    int r, c, j, i;
    scanf("%d%d", &r, &c);
    int **a = malloc(r * sizeof(int*));
    for (i = 0; i < r; i++) {
        a[i] = malloc(c * sizeof(int));
    }
    for (i = 0; i < r; i++) {
        for (j = 0; j < c; j++) {
            scanf("%d", &a[i][j]);
        }
    }
    spiral(a);
    for (i = 0; i < r; i++) {
        free(a[i]); 
    }
    free(a);
    return 0;
}

6 Comments

A pointer is not an array! OP wants a 2D array, you propose a much more complex array of pointers to array. And the code in spiral is apparently just a test. He will very likely need the dimensions anyway.
y, I kow those are different, but pointers to arrays are better in general. a true array is fixed in dimensions, but an array of pointers to array is much more flexible, so why explain it the easy way now, but if he wants to change anything then he is stuck
Sorry, but "but pointers to arrays are better in general" is nonsense! It depends on the application which you should use. And here a 2D array is the better approach, even if you malloc it. It is just used more often because people don't know how to handle a 2D array properly and correctly declare it. Once you understand the declaration, it is usually the better way to use an N-D array instead of multiple indirection - just think about a 3D array:being a 3-star programmer in C is not a compliment.
Oke I see you are against using pointers. I never learned anything else and i like the dynamic part of pointer arrays. How would you implement this without the pointers then?
If I really was against using pointer, C would definitively be the wrong language to use. int (*)[DIM2] very well is a pointer - you cannot pass an array to/from a function in C, only pointers to its elements. I'm agianst always using a hammer for every problem if you also have other tools which are more appropriate for a problem. It's not me being dogmatic here. OP is on the right track. Note that he also uses a pointer argument in his function declaration. For a good and correct implementation see Joachim's answer and my comment there (last part of course).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.