What prevents an array from being initialized with a variable size in C?

Asked

Viewed 1,767 times

22

Why does an array need to have a constant size? What prevents it from having a variable size?

3 answers

27


Confusion in the question

Nothing stops him, he can be dynamic according to C99 standard, although it is rarely used. Note that it is nothing magical, it is only a trick to give the illusion that the size varies.

But the common thing really is to be static.

Being static does not mean that it cannot have its size set at runtime, quite the contrary. So the question of the title is even a little weird (though understandable). Because the initialization of the array is variable yes, even in arrays static. These arrays cannot have their size changed at runtime.

Difficulty having elastic size

The size of no data type can be variable because of the organization of the memory. All you see that has variable size actually is a structure that uses some trick to change size. The most common tricks are:

  • copy the object to another place, the most used;
  • have a linked list, a tree or other data structure that breaks a larger structure into small interconnected pieces, then abstractly you see only one thing, but in concrete there are several data with constant size;
  • another type of structure that can generate this elasticity, in general something hybrid or derived from these, for example a tree.

This problem is similar to what causes file fragmentation. It is not a limitation of computers, even less of C, it is a physical-mathematical limitation.

Think that memory is a truck, you will put boxes inside it, as you will change the size of a box?

Let’s say she had the ability to grow on her own, she’d have to push all the others back. That would be a possibility, but imagine the cost of changing all the other data that might be behind the array that wants to increase in size. And imagine that changing places would have to change all the pointers for that data. It’s easier to abandon him and use a bigger new one.

It doesn’t matter if the data, in this case the array, will be allocated in the stack or in the heap, it needs to reserve a specific memory space. After this is allocated something else can be allocated right away.

How to increase the size of the previous data if soon after another thing was allocated?

Memória
-------------------------------------------------------------------
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-------------------------------------------------------------------
\_______________________________________/\______/\/\__/
       array de char total 20 bytes        int  char short

Show me how you would increase the size of array? Will move everything after?

The most that could do would be to decrease the size, but then would be a hole in the memory and the cost of managing these holes does not usually compensate for the gain that would have, wastes memory.

Memory allocation

In C the arrays are usually reserved in the stack. As it is a stack, in theory it would be possible to increase the size if nothing else is placed on it, but to know if it has something or would not complicate the functioning of the stack itself, making it worse in general use to have a marginal gain in the specific case.

If it is to decrease it is no use because what is stacked up would have to be moved, which would also defeat the purpose of using an organized stack and not a general stack (heap). And why touch something that will probably disappear soon?

Arrays in stack are usually simple and rarely need to have their size changed, in general when there is this need is a good indicator that should be using the heap. You can’t reallocate in stack, there is less control.

In computing everything is tradeoff. Then you might wonder, why not just have stack which is better than the heap? Or ask, why not just have heap that solves all cases? They are solutions to different problems. Just as you can choose how to simulate the size variability of a data structure according to each need.

In the heap the "arrays" work more freely, in general they are represented by a pointer to an allocated area. You can use a realloc() when you need to change your size, but you fall for that move the die. There is no miraculous way to solve this, after all two bodies cannot occupy the same place at the same time.

The use of arrays in the heap is a little more complicated than this, but I better simplify the definition for this purpose

Understand that arrays are not pointers in fact, as many people think they are in C. Pointers are used to simulate the behavior of a array and the access rating of array can be used to access memory addresses from a pointer. And of course it is possible to use the array even in the heap, but this is more common within another structure for reserve space within it, after all the function of the array in C is to reserve memory, and with pointers to the heap the allocation is usually made with malloc() already reserved the space.

Relocating is not so expensive

Memory itself is usually a linked list of pages (or some other structure that gives flexibility in mapping), so moving can cost less than it looks, since it can only rearrange pointers to pages (nodes) instead of moving the data. This depends on the operating system or a higher-level allocator that can be used over native OS allocation.

Another optimization that is common to avoid relocations is that these data structures often allocate a larger size than they really need by avoiding multiple relocations. And this tends to grow exponentially, so the more real the more space is reserved to avoid new relocations because that pattern tends to hold. It is common to exhaust the memory of a computer "parrudão" before making 30 relocations, being rare to get close to it and the first ones will be cheaper (when there are no other optimizations). Especially in cases where many relocations are expected it is common to start the array with extra size left.

It’s better to lose a little memory than to require so much processing.

High level data structures

Maybe except for C all languages mainstream have data structures in their standard library that handle the array fixed to have its size variable transparently, using one of the mentioned tricks. In general we use a vector or list or a array more abstract.

Every C programmer ends up discovering an extra library or making their own data structure that facilitates this kind of thing, but most C students never become professional programmers in C, So they never really need it as they never work with real problems. For college exercises or free study following some book or tutorial it will only have to deal with simple problems that you can do everything by hand without needing better abstractions.

There is also a certain culture among C programmers of not using many abstractions that can worsen performance, memory consumption or even hide what is being done. You can manage this variability in the hand without being transparent.

Completion

Can you initialize one array with an unknown size, it cannot be variable because nothing is initialized with something variable.

  • I saw you marked my post string "unlimited" however it was not clear to me what the relationship between them, although I found your explanation here very interesting, my doubt remains, what I understood (based on what I asked and your reference to this link) is that the only way to create a string without a pre-established limit would be through a stack of char, that is, create an entire data structure to receive truly modular values, that’s right?

  • @Runo here makes it clear that you can’t create anything unlimited, something that’s really elastic. What it can do is something that abstract the ability to change the size of the data, but it being unlimited even is not possible. If I were to answer there, I would basically respond to what is written here, maybe a little less, but certainly nothing more, so there’s no need to duplicate answers.I think you need to read the text again, pay attention and follow the links.One string "unlimited" is simulated by a list of char c/ array that changes your allocation whenever there is not enough space left

  • Yes, I understand that when it comes to computational resource it is physically impossible to create something unlimited, so from the quotes, but it has not yet become clear to me the way it would be done, because as far as I understand, both by array how much for pointer there is the need to declare the allocated space, however the proposed problem would be in the case of not knowing how much space the user would like to allocate, as the Notepad, which can be written a character or a text, when reading your explanation, what I understood was that the best way to do this would be through a pile, or got it wrong?

  • No, I didn’t talk about using a pile for this, what I’m talking about a pile is something else, it’s just the fact that there’s a limitation. You have to make a list on or tree or relocate when the size changes. I created a section just for this at the end and highlighted well the 2 tricks of the solution at the beginning.

  • Ah ok, I think I got the idea, but I was confused about how to use the realloc() (found a little vague the example and the explanation of the official website), but I will give a studied here, see some books, manuals, tutorials on. Thank you.

  • The problem is not changing the size of the zone. We did this in the 1980s with the development of a "Memory Manager" in Atari. The problem is the data. Imagine that you have a "string" in memory and in another place the address of this "string". If you increase the space used, we can imagine that you will have to copy the "string" in the other place. And right now the string address will not be but the bandstand address. Worse if in your memory zone you have "code" and not only data. In theory, it is certain. In practice it is not so easy... See https://en.wikipedia.org/wiki/Relocation_(computing)#Unix-like_systems

Show 1 more comment

8

In a simplistic way, a array in C is nothing more than a pointer pointing to an allocated memory region whose size is the result of multiplying the amount of elements by the size in bytes of each one.

In practice, nothing prevents you from using as many elements as you want, beyond the upper limit of the elements, however as you have not reserved that space, the chances are that you will end up reading or writing some other structure and possibly triggering an error on systems with protected memory.

What confuses those who use C after contact with higher-level languages is the expected behavior of certain data structures, that is, that they do some automatic control in certain situations.

This would be possible if an array were an object, adding certain logic to the method of adding elements, or if access to the array were delegated to some system routine instead of going straight into memory. However, in both cases the advantage of the C language is lost, which is the maximum efficiency in access, because the code is compiled directly for references in memory and not in calls to intermediate routines.

2

Nothing prevents an array from having variable size:

#include <stdio.h>

int main(void) {
    int tamanho;
    scanf("%i", &tamanho);
    int array[tamanho];
}
  • 3

    Variable Length Array (VLA) was introduced in C in version C99. Compilers for earlier versions of the language do not contemplate this capability (the Microsoft compiler, Visual Studio 2013, for example).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.