I would like to know how a variable length array is managed (what extra variables or data structures are kept on the stack in order to have variable length arrays).
Thanks a lot.
It's just a dynamically sized array (implementation-dependent, but most commonly on the stack). It's pretty much like alloca in the old days, with the exception that sizeof will return the actual size of the array, which implies that the size of the array must also be stored somewhere (implementation-dependent as well, but probably on the stack too).
The size of variable length arrays is determined on run-time, instead of compilation time.
The way it's managed depends on the compiler.
GCC, for instance, allocates memory on the stack.But there is no special structure. It's just a normal array, whose size is known at run-time.
alternatively you could use some containers, e.g. ArrayList in java or vector in c/c++
Related
If I declare an array double x[n] where n is either a constant or an int variable, I can get it's size during runtime. But if I allocate memory using malloc this does not happen. Is this because of stack vs heap memory allocation ? If so how are array sizes for global variables determined and why can't I declare variable length arrays as global variables ? and how does deallocation work since you need to know how much memory to free ?
The answer to basically all of your questions is that the memory allocator privately knows how much memory it allocated, but not the type of your object. In fact, it might only know how many blocks of some fixed size it allocated, not necessarily the same as the number of bytes requested. Therefore it does not know how many elements that "array" contains, or even if it's being used as an array at all.
You are expected to keep track of usage-specific information yourself if you need it. You simply request however many bytes you need and then use that memory however you choose. It is not the allocator's responsibility to assist you with this, which gives you full flexibility to do whatever you want.
The array x in your example has a known type and size at compile time, or can be inferred at runtime. In other words, the compiler knows that it should push some number of bytes onto the stack based on the size value and use them as an array of the defined type.
It makes less sense to have VLAs at global scope, since the whole point of the VLA is that it is allocated based on the variable size when entering a block scope. The global scope is only entered once when your program is initialized.
During translation, the compiler keeps track of all variable definitions and their sizes. Except for VLAs, the sizeof operator is evaluated at compile time, not runtime. How the sizes of VLAs are tracked is up to the individual implementation.
I read an article about Dynamically Sized Arrays on ITJungle and was wondering if this is not an "making easy thing much more complex" thing.
So as I understand if I define an static variable, including arrays, the runtime reserves the needed space at RUNTIME. So when defining a array of CHAR(10) DIM(10) the whole space would be reserved when starting the program.
So as the article says if I want to have a dynamically increasing array which resizes itself to fit the data like an List<String> in C#, I have to create a CHAR(10) DIM(10). I then have to re-allocate new space only if needed?
Why? The space is already reserved. What reason would someone have to base a array with (lets say) 100 bytes size on a pointer when only needing i.e. 80 bytes?
Am I just missing something? Is the "init-value" for sizing the array just to calm down the compiler so I don't get an error that the "compiler doesn't know the size at compile time"?
For normal arrays, you are correct that the space gets allocated at runtime as soon as the particular arrays scope is reached (start of the program for globals, start of subprocedure for subprocedures).
However, you will notice that the data structure is declared with based(pInfo). based is the keyword that will cause the memory to NOT be allocated. It will instead assume the all the memory for the data structure (included the array member) is already allocated at the location specified by the pointer passed to the based keyword (pInfo in this case).
Effectively, once you use the based keyword you are simply telling the compiler how you would like the memory at the specified pointer to be used but it is up to you to actually manage that memory.
In summary, if I understand your question properly, the statement you made about "knowing the size at compile time" is correct. RPG does not support pointer/array duality or array-like objects like some languages so you essentially just have to declare to RPG that you will NEVER go beyond "init-value" bounds.
When working with arrays of the same length, consider creating a structure which only contains an array so that it is easier to copy the array by simply copying the structure into another one.
The definition and declaration of the structure would be like this:
typedef struct {
char array[X]; /* X is an arbitrary constant */
} Array;
Array array1;
Then, perform the copy by simply doing:
Array array2;
array2 = array1;
I have found that this as the fastest way of copying an array. Does it have any disadvantage?
Edit: X is an arbitrary constant, let's say 10. The array is not a variable length array.
X may be arbitrary (up until the limits of your compile environment), but it's (naturally) the same number for all objects of type Array. If you need many arrays of same length and type to be copied to each other, there's nothing inherently wrong about this, although accessing these arrays might be more cumbersome than usual.
Array array1;
array1.array[0] // to access the first element
This works fine, but since X must be defined at compile-time it is rather inflexible. You can get the same performance over an array of any length by using memcpy instead. In fact, compilers will usually translate array2 = array1 into a call to memcpy.
As mentioned in the comments, whether direct assignment gets translated into a memcpy call depends on the size of the array amongst other compiler heuristics.
It's entirely dependent on the compiler and level of optimizations you use. The compiler "should" reduce it to memcpy with a constant size, which should in turn be reduced to whatever machine specific operations exist for copying various size blocks of memory. Small blocks should be highly machine specific these days. Actually calling the memcpy library function to copy 4 bytes would be so "10 years ago."
With optimizations off all performance bets are off.
I am new to C programming. I am trying to set the size of the array using a variable but I am getting an error: Storage size of 'array' isn't constant !!
01 int bound = bound*4;
02 static GLubyte vertsArray[bound];
I have noticed that when I replace bounds (within the brackets on line 02) with the number say '20', the program would run with no problems. But I am trying to set the size of the array dynamically ...
Any ideas why I am getting this error ?
thanks much,
You are getting this error because, as the compiler told you, your array size is not constant. In C89/90 version of C language array size has to be a constant. You can't "set the size of the array dynamically". If you need a run-time sized array, you have to either allocate it manually with malloc or use some non-standard compiler-specific approach (like alloca function).
In C99 version of C language support for so called Variable-Length Arrays (VLA) was added. A C99 compiler would accept run-time sized array declaration for an automatic array. Yet even in C99 you can't declare a static array of run-time size, as you are trying to.
To create an array of a non-constant size (i.e. known at compile time), you need to dynamically allocate space for it using malloc() (and correspondingly deallocate it using free() when it is no longer required).
As others have noted, the ability to declare dynamic arrays is available in C99 compliant compilers.
What you want is possible in C99; however, with earlier versions of C, you are stuck calling functions to dynamically allocate memory, e.g. alloca(3) or malloc(3).
use either of these
GLubyte* vertsArray = (GLubyte*) malloc(sizeof(GLubyte) * bound);
GLubyte* vertsArray = new GLubyte[bound];
remember to free the memory when you don't need the object anymore
delete [] vertsArray;
free((void*)vertsArray;
Despite what they say in the comments I still say that you should prefer new instead of malloc if you are not 100% forced to use C. See this link for more information
I know its possible to increase the size of a dynamically allocated array.
But can I increase the size of a statically allocated array?
If yes,how?
EDIT: Though this question is intended for C language, consider other languages too.Is it possible in any other language?
Simple answer is no, this cannot be done. Hence the name "static".
Now, lots of languages have things that look like statically allocated arrays but are actually statically allocated references to a dynamically allocated array. Those you could resize.
in VB .NET it would be:
Redim Preserve ArrayName(NewSize)
not sure what langauge you're after though...
And I wouldn't use this command a lot... its terribly inefficient. Linked lists and growing data structures are much more efficient.
No. It is not. There are two options here:
Use a dynamic one
Or,at the risk of wasting memory, if you have an idea about the maximum number of elements that the array will store, statically allocate accordingly
Yes, that was C.
If you're careful, you can use alloca(). The array is allocated on the stack, but in terms of the code style it's a lot like if you used malloc (you don't have to free it though, that's done automatically). I'll let you decide whether to call that a "static" array.
No. Static allocation gives the compiler permission to make all kinds of assumptions which are then baked into the program during compilation.
Among those assumptions are that:
it is safe to put other data immediately after the array (not leaving you room to grow), and
that the array starts at a certain address, which then becomes part of the machine code of the program; you can't allocate a new array somewhere (and use it) because the references to the address can't be updated.
(Well, references could be updated, if the program was stored in ram, but self-modifying programs are highly frowned upon, and surely more trouble than dynamic arrays.)
Technically, in C it isnĀ“t even possible to increase the size of a dynamically allocated array.
In fact, realloc() does some kind of "create new object & copy the data" routine. It does not modify the size of an existant heap-memory object at all.
So the answer is simple as that, that you are not be able to change the size of any object or array of objects after it has been allocated, neither if it was dynamically or statically allocated.
What you can do is to use the same strategy by developing a function which is creating another static allocated array of objects with the desired size and copy the data. If the new array of objects is smaller than the old one, the values inside the difference are discarded.
The only difference is, that the size of the new array, equivalent to the size of the old array, need to be fixed at compile-time.