i am solving a problem. In my code i have two arrays
array[];
array2[];
i am inputing 2 numbers through scanf , and i want the size of arrays to be the count of number 1 and 2 e.g
int x;
int y;
scanf(" %d %d\n",&x,&y);
int indexX[x*y];
int indexY[x*y];
This does not work.
Being new to C im quite lost how to implement it , is the only way dynamicly allocate memory? If no , how can i achieve wanted result ? Or how could i dynamicly alocate the memory for it?
my code throws error
warning: ISO C++ forbids variable length array ‘indexX’ [-Wvla]
warning: ISO C++ forbids variable length array ‘indexY’ [-Wvla]
According to your error messages, you compile with a C++ compiler. Do not! C is not C++ and C++ is not C with classes. They are different languages. As the messages state, C++ does not provide VLAs (see below).
Use a standard-compliant C compiler, or at least a C99 compiler. Variable length arrays (VLAs) were added with the C99 release of the standard as a mandatory feature. C11 relaxed this by making it optional, but most (if not all) compilers which support C99 also implement it in C11 mode.
before defining the array, you should verify scanf really set these two variables by checking the result of scanf. Otherwise you use uninitialised variables, which is undefined behaviour and may (likely - will) result in strange behaviour - at best.
Additinally you can also initialise the variables before scanf to 1 (a VLA of size 0 is also undefined behaviour). This way you can check later and are still safe with the VLA definition.
Warning: Most, if not all modern implementations place VLAs on the stack. The size of the stack is normally limited to some 100 bytes (embedded systems) up to some MiB (standard OS like Windows, OS-X, Linux). There is no check if the VLA fits onto the stack, so you should not allocate too large arrays. If you are not sure, better use dynamically allocated memory (malloc& friends).
Related
This code:
int main() {
int size;
scanf("%d", &size);
int array[size];
}
works fine with GCC, but VC expects a constant expression for the size of the array so does not compile it (which makes more sense to me). Any idea why it works with GCC?
Yes, because gcc supports variable length arrays.
It was added as a part of C99 standard, however, in the later standards (C11 and C18), it's an optional feature.
Because variable-length arrays (VLAs) are neither valid in C90 nor C++11 MSVC does not support them:
From https://learn.microsoft.com/en-us/cpp/build/reference/za-ze-disable-language-extensions?view=vs-2019:(
The C compiler is an C89/C90 compiler that, by default, enables
Microsoft extensions to the C language.
VLAs may be best avoided in any event because a C11 compiler need not implement them and they are potentially unsafe. Typically an implementation will allocate VLAs on the stack. In your code, it only takes a user to enter an arbitrarily large value to break your code in someone-deterministic manner - any use of VLAs should have some constraint test to ensure the length is reasonable and in the capability of the system to support.
during some code refactor in C++ i meet following local variable length arrays
void some_function(uint8_t length, uint8_t id, uint8_t * bytes)) {
uint8_t string[length + 8];
//some transformation on string [1-8] elements
do_something(string);
}
I am not familiar with C99 but using Variable-length array size [x+y] look like this will be placed in heap. Also I debug this function to make sure that this "string" variable is placed on heap and it is.
In C local variables can't be fixed size, so they are not needed to clean up after using them. But here we have fixed size array without memory allocation, so is no need to clean up after this variable, but how GCC compiler manage this memory?
Or maybe on other way to clarifying what I am considering here: length variable is coming from external IO so in my opinion there can be security issue (for example when length will be INTEGER_MAX value), besides check the size of length what other actions can be taken to have secure code here? Or maybe it is already secure?
What you see in this code is a C99 Variable Length Array. A similar proposal almost made it to C++14, but didn't. So this code is not valid STANDARD C++, but your compiler may support it. AFAIK, C99 VLAs store their memory on the stack.
See this question and this one. It's a GCC extension:
Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++. These arrays are declared like any other automatic arrays, but with a length that is not a constant expression. The storage is allocated at the point of declaration and deallocated when the block scope containing the declaration exits.
So for example,
int aaa(unsigned int par1, unsigned int par2){
int array[par1*par2];
return 0;
}
I tried compiling the code that contains this, and it compiled well and had no run-time issue - the array was properly created.
But I know that this is basically declaring a dynamic array in static array declaration fashion. What may go wrong with this declaration? Will there be a compiler issue in a different compiler?
This is correct as per the 1999 C standard. The 2011 standard changed it to be an optional feature, which in practice means that all C11 compilers will support it except for MSVC.
Before 1999 some compilers offered this as a non-standard extension.
Here is a link to StackOverflow search for other questions on this topic.
But I know that this is basically declaring a dynamic array in static array declaration fashion.
This is called VLA (Variable-Length Array). This array is not static - it is placed in automatic memory (also known as "the stack").
What may go wrong with this declaration?
It may overflow the stack when the size of the array exceeds a certain limit specific to your system.
Will there be a compiler issue in a different compiler?
This is a C99 feature, so compiler that do not support C99 may fail to compile this code.
I believe this is a C99-only feature. It's called VLA (variable-length arrays).
The C++0x does't support VLA:
https://groups.google.com/forum/#!topic/comp.std.c++/K_4lgA1JYeg
But some compilers might not be strictly compliant with the standard.
Following piece of code compiles in gcc. But it is not correct way of writing as it surpasses the use of malloc function. What is the problem in this code?
#include<stdio.h>
main()
{
int n;
scanf("%d",&n);
int a[n];
}
your code is legal ISO C99 code. It's not C89 ANSI compliant: if you are stuck with compatibility rules, because of old compilers or company policies, you need to use malloc().
More importantly, in C99, using your definition, the array is allocated on stack, that is usually a limited resource, while with malloc() it's allocated in the heap.
Your array is a variable length array (VLA). This is an advanced feature of C, introduced in the C99 version of the standard.
The problem with VLAs is that they can easily overflow the stack. Unless you have a specific reason to use a VLA, use dynamic memory with malloc and avoid the risk of stack overflow.
Your main declaration is wrong. It should be
int main(void)
"...it is not correct way of writing as it surpasses the use of malloc function..." - what is that supposed to mean? According to the rules of modern C language, the only problem with your code is the missing int in the declaration of main. I.e. it has nothing to do with any malloc.
It can be said that your code is self-contradictory in a sense that it uses a perfectly valid C99 feature - variable length array int a[n] - but at the same time relies on an obsolete feature of C89/90 - implied int in the declaration of main, which is no longer supported by C99.
You need to decide which version of C language you are trying to use - C89/90 or C99. Once you make that decision, we'll be able to discuss the correctness of your code.
I know that I'm not supposed to do this in C90, and it's a rather basic stuff.
char name[strlen(s)];
ArrayLength.c:11: warning: ISO C90 forbids variable length array ‘name’
Did they want me to specifically use malloc? I'm just curios here about the logic behind it.
It's forbidden because C90 doesn't support variable-length arrays (VLAs). It's really as simple as that.
Your options are:
Declare a fixed-length array that can cope with the maximum string length you want to work with.
Dynamically-allocate the array (using malloc).
Work with a compiler that offers VLAs a non-standard language extension, e.g. GCC. (I don't recommend this, because it means you'll end up writing non-portable code.)
Use C99 instead, where VLAs are supported. Note that VLAs are allocated on the stack, which can cause all sorts of issues if you run out of stack space (unlike with malloc, there's no concept of being able to check that the allocation was successful).
[Note: If you're allocating an array in order to make a copy of s, you'll need to use strlen(s)+1 as the size (remember the null terminator).]
It's not that "they" don't want you to do it, it's simply not part of the language (or rather, wasn't prior to 1999). The standard workaround is to use malloc or alloca. (alloca is essentially identical to variable length array allocation, but is not a standard function, so it may not be available on all systems of interest. Also, some people have strong objections to it's use, but they tend to object strong to variable-length arrays for the same reasons.)
This warning points to the usage of a GNU gcc extension is a serious portablity problem.
The code is illegal, because the value of strlen(s) is not known at compile time. GNU gcc provides an extension for automatic arrays that allocate based on run time values; but relying on these makes the code out of compliance with the standard.
If the value of strlen(s) isn't known until run-time then one can bring the code into compliance by either converting to performing the allocation/deallocation explicitly on conventions arrays, or by using STL containers.(e.g. std::vector).
It's a matter of the language having restrictions for the presumed convenience of the
compiler and its intended runtime environment.