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.
Related
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.
I am having difficulties to find a possible solution so I decided to post my question. I am writing a program in C, and:
i am generating a huge array containing a lot of pointers to ints, it is allocated dynamically and filled during runtime. So before I don't know which pointers will be added and how many. The problem is that they are just to many of them, so I need to shrink somehow the space.
IS there any package or tool available which could possibly encode my entries somehow or change the representation so that I save space?
Another question, I also thought about writing a file with my information, is this then kept in memory the whole time or just if I reopen the file again?
It seems like you are looking for a simple dynamic array (the advanced data type dynamic array, that is). There should be many implementations for this out there. You can simply start with a small dynamic array and push new items to the back just like you would do with a vector in c++ or java. One implementation would be GArray. You will only allocate the memory you need.
If you have to/want to do it manually, the usual method is to store the capacity and the size of the array you allocated along with the pointer in a struct and call realloc() from within push_back() whenever you need more space. Usually you should increase the size of your array by a factor of 1.3 to 1.4, but a factor of 2 will do if you're not expecting a HUGE array. If you call remove and your size is below a certain threshold (e.g. capacity/2) you shrink the array again with realloc();
I'm looking for a way to allocate additional memory (in C) at runtime, for an existing structure (that already had its memory assigned initially). I have a feeling I might be able to use memmove or something similar but that's still just a copy operation, and doesn't increase the amount of memory available to a structure at runtime. Also I don't want to have to copy the entire structure every time I need to do this, which will be many hundreds of times during the program (the structure is already huge). Can anyone help?
UPDATE: Thanks everyone for the replies. To give more detail, what I am trying to do is run an MPI-parallelised code that creates many instances of the structure (call it 'S') initially. Each instance of the structure contains an array 'T' which records the time of a particular event happening as the code is run. These events occur at runtime, and the number of events differs for each instance of S. For example, S[0] might see 100 events (and therefore need an array of 100 elements in length) but S[1] might see only 1 event (and S[2] 30 events, etc.) Therefore it would be very wasteful to allocate huge amounts of memory at the start for every instance of S (for which there are millions) since some might fill the array but others would not even come close. Indeed I have tried this and it is too much for the machine I am running it on.
I will try some of the ideas here and post my progress. Many thanks!
You could probably use realloc().
There is no way to do what you describe, because there is no way to guarantee that there will be available memory next to the one that your structure is currently occupying.
The standard thing to do is to allocate more memory and copy your data.
Of course if you can know (an estimate of) the size of the memory allocation that you need you can preallocate it and avoid copying.
Note, however, that the structures in C have a fixed size once they are declared, so it seems you don't really need to allocate more memory for an existing structure...
realloc is the only way to expand the existing dynamic memory. realloc will tries to expand the existing buffer, if it fails in expansion it will allocate new buffer for the total size required and it will copy the data from old buffer. If you dont want to do realloc every time(which internally will memmove most of the time) then you can try to reallocate more memory than actually you required.
realloc(buf_ptr, (actual_size + additional_size) * 2);
This way will reduce the frequency of calling realloc (and memmove).
Note : Implementation of realloc is different in some architecture, it will never tries to expand the memory it always tries to allocate buffer for total size. So in those platforms memmove will be called for every call to realloc.
It sounds like you are looking for the C feature called flexible array member (example). It is only well-defined for C standard C99 or later.
The last member of the struct will have to be declared as a flexible array member, which you initially malloc, and later realloc (and of course memcpy to do the actual copying).
If I want to create a 2D array, with dimensions specified by user input, can't I just do this sequentially in the main function? Once I have the dimensions by using scanf, I then create an array with those dimensions? From what I understood, malloc is supposed to be used when the space required is not known at runtime. I wouldn't've known the space required at runtime but I didn't have to allocate the memory dynamically, and it would work anyway, right? Perhaps I'm completely misunderstanding something.
Generally there are three reaons to use dynamic allocation in C:
The size is not known until runtime (another alternative is VLA's, but that's C99 and potentially dangerous, see reason 2).
The size is (most likely) too big for the stack, risking stack overflow.
The object needs to live on the heap giving it a longer life than "automatic" storage.
malloc is generally used when the space requirements aren't known at compile-time, or when you need the object to persist beyond the scope that it was created in.
In C99 (unlike earlier versions of C), you can also define variable-length 1-dimensional arrays without using malloc. But many people consider then evil, because there's no way to catch an out-of-memory condition.
But if you want something that acts like a multidimensional array (in the sense of being able to index it like x[i][j]) where the dimensions aren't known until runtime, you will need to involve malloc somewhere.
Here's a archetypal example of the need for dynamic allocation: Making a dynamic container. Since you don't know the number of elements in advance, each element has to be allocated dynamically. Since you populate the container in a loop, each element must outlive the loop scope. This is the "zero-one-many" rule at its barest, and the "many" part of it immediately entails dynamic allocation:
int value;
node * my_list = NULL;
while (get_one_more_input(&value) == SUCCESS)
{
node * elem = malloc(sizeof(node));
elem->data = value;
elem->next = my_list;
my_list = elem;
}
The crux here is that the actual list node is only populated inside the loop which reads the input data, but clearly it must outlive that scope. Thus no automatic object can do, because it would only live to the end of the scope, and also no static element could do, because you cannot know the number of loop iterations beforehand. Dynamic lifetime and storage management is the only solution here, and that's what it is primarily intended for.
In C you will be doing a lot of this by hand, since dynamic data structures are at the very heart of computing. C++ makes a lot of this much easier and safer by wrapping all the dynamic management logic into hidden-away, reusable code that you never need to look at as a consumer (though it's still doing the exact same thing).
I think all malloc(sizeof(structure)) can be replaced this way:
char[sizeof(structure)]
Then when is malloc necessary?
When you don't know how many object of some kind you need (e.g. linked list elements);
when you need to have data structures of size known only at runtime (e.g. strings based on unknown input); this is somewhat mitigated by the introduction of VLAs in C99, but see the next point:
when you know at compile time their size (or you can use VLAs), but it's just too big for the stack (typically a few MBs at most) and it would make no sense to make such thing global (e.g. big vectors to manipulate);
when you need to have an object whose lifetime is different than what automatic variables, which are scope-bound (=>are destroyed when the execution exits from the scope in which they are declared), can have (e.g. data that must be shared between different objects with different lifetimes and deleted when no one uses it anymore).
Notice that it isn't completely impossible to do without dynamic memory allocation (e.g. the whole rockbox project works almost without it), but there are cases in which you actually need to emulate it by using a big static buffer and writing your own allocator.
By the way, in C++ you will never use malloc()/free(), but the operators new and delete.
Related: a case in which trying to work without malloc has proven to be a big mess.
You will use malloc to dynamically allocate memory, either because:
you don't know at compile-time how much memory will be required,
you want to be able to reallocate memory later on (for instance using realloc),
you want to be able to discard the allocated memory earlier than by waiting for its release based on the scope of your variable.
I can see your point. You could think you could always using a declarative syntax for all of these, even using variables to declare the size of your memory spaces, but that would:
be non-standard,
give you less control,
possibly use more memory as you will need to do copies instead of re-allocating.
You will probably get to understand this in time, don't worry.
Also, you should try to learn more about the memory model. You don't use the same memory spaces when using a dynamic allocation and when using a static allocation.
For first pointers, visit:
Dynamic Memory Allocation
Static Memory Allocation
Stack vs Heap
Stack vs Heap?
How C Programming Works - Dynamic Data Structures
Friendly advice: I don't know if you develop C on *NIX or Windows, but in any case if you use gcc, I recommend using the following compilation flags when you teach yourself:
-Wall -ansi -pedantic -Wstrict-prototypes
You should read about dynamic memory allocation. You obviously don't know what it is.
The main difference between the two is that memory allocated with malloc() exists until you say so. Static memory such as char buff[10]; only exists in the function scope.
malloc is a dynamic memory allocator which helps u up to assign memory to ur variables according to ur need and therefore reduces the loss of memory.It is also supported by realloc() function through which u can edit the memory required which u have defined earlier through malloc() or calloc(). So in short we can say that malloc() can be used for managing the memory space and making use of the necessary memory without wasting it.
You never should do this the way you are proposing. Others already told you about the difference of allocating storage on the heap versus allocation on the function stack. But if and when you are allocating on the stack you should just declare your variable:
structure A = { /* initialize correctly */ };
There is no sense or point in doing that as an (basically) untyped char array. If you also need the address of that beast, well, take the address of with &A.
When you don't know how much memory to allocate at compile time. Take a very simple program, where you need to store the numbers entered by the user in linked list. Here you dont know how many numbers will be entered by the user. So as user enters a number you will create a node for it using malloc and store it in the linked list.
If you use char[sizeof(structure)] instead of malloc, then I think no dynamic memory allocation is done.
Besides the fact that your char[] method cannot resize or determine the size at runtime, your array might not be properly aligned for the type of structure you want to use it for. This can result in undefined behaviour.