8

I have been teaching myself programming for couple of years, and I was sure that if you need array declaration of a variable number you need to use malloc or new.

Today I found that this compiles under g++ version 4.4.4, without warnings or errors:

#include <iostream>
using namespace std;

int main()
{
    int size_array;
    cin >> size_array;
    int iTable[size_array];

    for(int i=0;i < size_array;i++)
        iTable[i]=i*i;
    for(int i=0;i < size_array;i++)
        cout << iTable[i] << endl;

    return 0;
}

Also it compiles completely fine if you are using gcc (after changing cout and cin with printf and scanf)

Under Visual Studio this code fails to compile since size_array is not constant.

When this was changed? This is a safe method?

3
  • C tag removed, as this code is not even remotely C. Commented Mar 21, 2011 at 12:17
  • Possibly duplicate: stackoverflow.com/questions/2427336/… Commented Mar 21, 2011 at 12:20
  • 1
    @DeadMG, Soltys notes that the question still applies if you use printf and scanf. The example is c++, the question is more general. Commented Mar 21, 2011 at 12:28

8 Answers 8

12

This is a C99 feature - VLA - which is not a part of standard c++. You can use it if your compiler supports it and you don't require portability. If the compiler supports it, it's perfectly safe to use - but it's a bad habit using non-standard features.

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

8 Comments

safe even if I put a size_array++ in the loop? surely not?
@Tom: Yes, it is. You won't change the size of the array doing that, though.
@Tom: Sure is. The stack for the VLA is allocated once and not changed, sizeof will provide the actual size. If you change the variable you use to indicate size of an array it doesn't matter whether it's VLA or not - it's a logic error.
@Erik: with C++0x being based on C99, do you know if they integrated VLA into C++0x or not ? A quick search through the standard did not yield anything useful.
@Erik: I must admit I quite like them, though the implementation soon gets tricky, especially when you want VLA within objects :D It might also have to do with vector being part of the STL, so they may not have felt as compelled as in C.
|
5

This is a compiler extension of gcc, not standard.

Comments

2

No thats not safe at all. It could corrupt your stack.

2 Comments

it could - what happens if he puts in -1?
+1 just tested this, and got memory corruption once I started allocating negative numbers. Needs to have a check for >0 before initializing.
2

See http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.20.

Simply put, in C99, this is called VLA and is part of the standard (correct me if I'm wrong) but in C++ this is not part of the standard. If you need this functionality use std:vector instead.

Comments

0

This depends if you are writing C or C++. I'll assume C as for c++ you would be better off using std::vector rather than an array.

In C it depends which versiuon you are using. If and only if you are using a C99 standard compiler then the array can take its size from a variable at run time as you do here otherwise the size must be defined at compile time. Visual Studio does not support the dynamic array - see MSDN

C++ uses the C89 standard so requires the size to be set at compile time.

So in your case you need to see what flags you passed to the compiler.

As noted by @Eric the code is C++ so the working compiler is using a non standard extention so for gnu I would add flags to enforce a standard e.g. -ansi or -std=c++98 and -pedantic

Comments

0

There is an extension of GCC mimicking C99 Variable Length Arrays. It's not standard C++.

However, even if you have this turned off, the posted code can compile. The standard does not require a diagnostic for this case: it's Undefined Behaviour, not an error.

In really obvious cases a compiler may choose to prevent you from writing this, but otherwise it is free to let you fail in peace.

Conclusion: don't be fooled by the compilation. It's still bad and wrong.

Comments

0

You can get this functionality in C or C++ with alloca (_alloca on Windows). std::vector is NOT a substitute: it is allocated on the heap, with new, which calls malloc, which is potentially expensive.

There is a good reason why you might want to have an array whose length is determined at runtime allocated on the stack: it's really fast. Suppose you have loop that executes frequently but has an array that depends on something at runtime (say, the size of your canvas widget). You can't just hard-code a number: your program will crash when we all get 36" 300 dpi Retina-display monitors and pixels[2400] is no longer safe. But you don't want new, or your loop hits a malloc and gets slow.

Although, for large arrays, it might be better to have a std::vector that is static to the function an only gets resized (larger) when necessary since your stack has limited size.

(See http://msdn.microsoft.com/en-us/library/wb1s57t5(VS.71).aspx)

Comments

0

It's okay to use the feature if you are using c99.

You have to be very careful about the value of size. a large value will overflow your stack, and your process may go insane.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.