0

What is the difference between this two array definitions and which one is more correct and why?

#include <stdio.h>
#define SIZE 20

int main() {

    // definition method 1:
    int a[SIZE];
    // end definition method 1.

    // defintion method 2:
    int n;
    scanf("%d", &n);
    int b[n];
    // end definition method 2.

    return 0;
}

I know if we read size, variable n, from stdin, it's more correct to define our (block of memory we'll be using) array as a pointer and use stdlib.h and array = malloc(n * sizeof(int)), rather than decalring it as int array[n], but again why?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Dragos Rizescu
  • 3,380
  • 5
  • 31
  • 42
  • 1
    A difference not mentioned in the answers below is, of course, that method 1 only works if you know at design time (that is, when you're writing the program) how many items the end user will need. Ever. With dynamic arrays, the end user can have as many items as they like. – Mr Lister Nov 23 '13 at 12:42

9 Answers9

6

It's not "more correct" or "less correct". It either is xor isn't correct. In particular, this works in C, but not in C++.

  • Ok, but which one is correct to use in C? Or it doesn't matter in this case? – Dragos Rizescu Nov 23 '13 at 12:24
  • @DragosRizescu If you use the array only locally, then there's no reason to use `malloc()`, so I'd prefer the VLA approach. If you do need to return it from the function, then you can't use a local array, because it's destroyed on return, so you then need `malloc()`. –  Nov 23 '13 at 12:28
3

You are declaring dynamic arrays. Better way to declare Dynamic arrays as

int *arr;  // int * type is just for simplicity
arr = malloc(n*sizeof(int*));  

this is because variable length arrays are only allowed in C99 and you can't use this in c89/90.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 3
    But in C++, you don't really use `malloc()` either. `std::vector`, or at most `new[]`. Also, I see no reason in this particular case for using `malloc()` -- the variable is only used locally, from within a function. –  Nov 23 '13 at 12:30
  • @H2CO3; Thanks for correcting me about `malloc` in C++. But VLAs are allowed only in C99 that's why I think `malloc` is better. – haccks Nov 23 '13 at 12:34
  • I am wondering why people after downvoting avoid to comment on the post. – haccks Nov 23 '13 at 12:43
  • @H2CO3; Thanks :). Every week on SO I saw questions about claiming that VLAs is not working (as they are not compiling their program in C99 mode) or what type of this is (not aware about VLAs). :) – haccks Nov 23 '13 at 12:48
  • Because "this widely-available and standard feature doesn't work in a doubly-outdated version of C, therefore using the complicated, non-native workaround is better" is *wrong*. This answer is *wrong*, unless the question is about C89, which it isn't: it is about C (and C++). C has a feature to do this, and that feature is VLAs. – Alex Celeste Nov 23 '13 at 14:17
  • Variable length arrays are an optional feature in C 2011. It is incorrect to state without qualification that you cannot use them. – Eric Postpischil Nov 23 '13 at 14:23
  • @EricPostpischil; I was not sure about C11 but I am sure about C89/90. – haccks Nov 23 '13 at 14:25
  • @Leushenko; I do not think using `malloc` is complicated. *This answer is wrong, unless the question is about C89, which it isn't* : I disagree that C means exclude C89. – haccks Nov 23 '13 at 14:29
2

In (pre-C99) C and C++, all types are statically sized. This means that arrays must be declared with a size that is both constant and known to the compiler.

Now, many C++ compilers offer dynamically sized arrays as a nonstandard extension, and C99 explicitly permits them. So int b[n] will most likely work if you try it. But in some cases, it will not, and the compiler is not wrong in those cases.

Jose Torres
  • 347
  • 1
  • 3
2

If you know SIZE at compile-time:

int ar[SIZE];

If you don't:

std::vector<int> ar;

I don't want to see malloc anywhere in your C++ code. However, you are fundamentally correct and for C that's just what you'd do:

int* ptr = malloc(sizeof(int) * SIZE);
/* ... */
free(ptr);

Variable-length arrays are a GCC extension that allow you to do:

int ar[n];

but I've had issues where VLAs were disabled but GCC didn't successfully detect that I was trying to use them. Chaos ensues. Just avoid it.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 2
    There's absolutely no reason whatsoever to `malloc()` in C (>=99) if one doesn't need to use the array outside the function. Also, "Variable-length arrays are a GCC extension" is only true for C++ (and that's not clear from your answer). –  Nov 23 '13 at 15:28
1

I think that metod1 could be little bit faster, but both of them are correct in C.

In C++ first will work, but if you want to use a second you should use:

 int size = 5;
 int * array = new int[size];

and remember to delete it:

 delete [] array;
Serafins
  • 1,237
  • 1
  • 17
  • 36
1

I think it gives you more option to use while coding.

If you use malloc or other dynamic allocation to get a pointer. You will use like p+n..., but if you use array, you could use array[n]. Also, while define pointer, you need to free it; but array does not need to free.

And in C++, we could define user-defined class to do such things, and in STL, there is std::vector which do the array-things, and much more.

haccks
  • 104,019
  • 25
  • 176
  • 264
thinkinnight
  • 141
  • 1
  • 1
  • 6
1

Both are correct. the declaration you use depends on your code.

The first declaration i.e. int a[size]; creates an array with a fixed size of 20 elements. It is helpful when you know the exact size of the array that will be used in the code. for example, you are generating table of a number n up till its 20th multiple.

The second declaration allows you to make an array of the size that you desire. It is helpful when you will need an array of different sizes, each time the code is executed for example, you want to generate the fibonacci series till n. In that case, the size of the array must be n for each value of n. So say you have n = 5, in this case int a [20] will waste memory because only the first five slots will be used for the fibonacci series and the rest will be empty. Similarly if n = 25 then your array int a[20] will become too small.

Rabbiya Shahid
  • 422
  • 3
  • 14
1

Q1 : First definition is the static array declaration. Perfectly correct. It is when you have the size known, so no comparison with VLA or malloc().

Q2 : Which is better when taking size as an input from the user : VLA or malloc .

VLA : They are limited by the environment's bounds on the size of automatic allocation. And automatic variables are usually allocated on the stack which is relatively
small.The limitation is platform specific.Also, this is in c99 and above only.Some ease of use while declaring multidimensional arrays is obtained by VLA.

Malloc : Allocates from the heap.So, for large size is definitely better.For, multidimensional arrays pointers are involved so a bit complex implementataion.

Check http://bytes.com/topic/c/answers/578354-vla-feature-c99-vs-malloc

Rafed Nole
  • 112
  • 1
  • 4
  • 16
0

The difference if you define array using malloc is that, you can pass the size of array dynamically i.e at run time. You input a value your program has during run time. One more difference is that arrays created using malloc are allocated space on heap. So they are preserved across function calls unlike static arrays.

example-

       #include<stdio.h>
       #include<stdlib.h>
       int main()
       {
           int n;
           int *a;
           scanf("%d",&n);
           a=(int *)malloc(n*sizeof(int));
           return 0;
       }
Neeraj Kumar
  • 803
  • 2
  • 8
  • 11
  • *if you define array using malloc is that, you can pass the size of array dynamically i.e at run time* : same is true for VLAs. – haccks Nov 23 '13 at 12:53
  • 1
    Don't cast the return value of `malloc()`. –  Nov 23 '13 at 19:05
  • @H2CO3 yeah, iam aware there is no need to cast in C, but doing it doesnot hurt, right? – Neeraj Kumar Nov 25 '13 at 08:06
  • @NeerajKumar But yes it does. [It hurts badly (link)](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). It decreases readability and it can hide errors. It has no benefits, it's only ugly and dangerous. –  Nov 25 '13 at 10:55