Contiguous multidimensional arrays - arrays

I'd like to find a way to have a DST that is a multi-dimensional array, but with the underlying memory being contiguous. The contiguous requirement is mostly born from the fact that I'd like this array to have roughly the same shape as a multidimensional C VLA (but on the heap, since Rust doesn't support arbitrary stack allocations).
I'd prefer something that is not part of a third party library or doesn't require too big a definition - I'll be generating code including this, so I'd prefer the generated code not rely on a third party library or have a giant definition.
The main thing that would be nice would be to have index operations (which keep returning other multi-dimensional slices), preferably with std::mem::size_of_val returning the right size for the array, as well as indexes into the array.
Is this even possible?

Related

C program with pointer

is it possible to convert any program written in C using pointer into another c program that does not contain any pointers?If yes, can we automate the process?
i read a few papers on c to java bytecode compilation and found that a major issue was "the pointer problem".so i was thinking that if the above process could be done,then it could be included like a preprocessing step(though it itself may be big task) and then it may be simpler to try converting to jvm bytecode...
thanks in advance
In theory you can, by simulating individual data structures or even the entire memory (static data, heap and stack) with arrays. But the question is whether this is very practical; it may involve having to rewrite every pointer-based standard library function you need.
Anyway, there's a nice explanation on Wikipedia:
It is possible to simulate pointer behavior using an index to an (normally one-dimensional) array.
Primarily for languages which do not support pointers explicitly but do support arrays, the array can be thought of and processed as if it were the entire memory range (within the scope of the particular array) and any index to it can be thought of as equivalent to a general purpose register in assembly language (that points to the individual bytes but whose actual value is relative to the start of the array, not its absolute address in memory). Assuming the array is, say, a contiguous 16 megabyte character data structure, individual bytes (or a string of contiguous bytes within the array) can be directly addressed and manipulated using the name of the array with a 31 bit unsigned integer as the simulated pointer (this is quite similar to the C arrays example shown above). Pointer arithmetic can be simulated by adding or subtracting from the index, with minimal additional overhead compared to genuine pointer arithmetic.
Pointers are rather central to C. While C may be turing-complete without pointers, it's not practical to rewrite arbitrary C without them.Things you can't do without pointers:-dynamic (manual) memory allocation.-passing by reference.Given that arrays decay into pointers a the drop of a hat, you also couldn't use arrays practically, so you are left with automatic, static and global variables that cannot be arrays. tl;dr: No

Dynamic vs dynamically created arrays in C

I'm in a Programming I class and this is an excerpt from my textbook:
"There are two basic ways to create an array, statically and dynamically. Note that a dynamically created array is not the same thing as a dynamic array; a dynamically created array can only be fixed-size in C. "
My professor is saying things that pretty directly contradict this quote, and is being very evasive when I ask further questions. He doesn't seem to acknowledge that there is a difference between dynamic vs fixed-size and dynamically-created vs. statically-created. I don't know enough about C to argue with him and since he's the one who wrote the textbook, I'm a little lost at the moment.
What is the difference between statically-created vs. dynamically-created and dynamic vs. static arrays?
Do "dynamic" (not dynamically-created) arrays exist in C?
The textbook is "The Art and Craft of Programming: C Edition" by John Lusth. Actually I was wrong about my professor being the one who wrote it, the author is a different CS professor at my school.
When the professor uses word dynamic it means that an array can change its size on the fly. That is new elements can be added to or deleted from the array.
A dynamically allocated array means the allocation of an array at run-time in the heap. Statically allocated arrays are allocated before the main function gets the control.
Take into account that C has Variable Length Arrays (VLA). Bit it is not the same as dynamic arrays. VLA means that an array may be recreated with different sizes. But in each such recreation you create a new array.
An example of a dynamic array is standard C++ class std::vector.
The answer to this question will depend on how pedantially one wants to treat terms like "array" and "dynamic". Is "array" supposed to refer exclusibely to array types? Or are we allowed to include malloc-ed arrays as well, accessible through pointers? Does "dynamic" refer to dynamic memory (even though the standard C nomenclature does not use this term)? Or are we allowed to consider local VLAs as "dynamic" as well?
Anyway, one can separate arrays into three conceptual categories
Arrays with compile-time size
Arrays with run-time initial size, which cannot be resized
Arrays with run-time initial size, which can be resized
Apparently, your professor referred to the second category as "dynamically created arrays" and to the third category as "dynamic" arrays.
For example, arrays from the first category are the classic built-in C89/90-style C arrays
int a[10];
Arrays from the second category are C99 VLAs
int a[n];
(or new-ed arrays in C++).
Arrays from the third category are arrays allocated with malloc
int *a = malloc(n * sizeof *a);
which can be later resized with realloc.
Of course, once we step beyond the built-in features of the core language, the division between these categories becomes purely conceptual. It is just a matter of the interface the array implementation offers to the user. For example, it is possible to implement arrays from the third category through arrays of the second category, by destroying the old fixed-size array and allocating a new one of different size. In fact, that is how realloc is allowed to work in general case.
The issue here is that the terminology is not formally defined, so when different people use these words, they may mean different things.
I think your textbook is distinguishing between these three definitions:
Static array
An array whose size is hard-coded into the source:
int ages[100];
ages[0] = 1;
Disadvantage: you have to know how big to make it, when you code.
Advantage: the runtime automatically takes back the storage when the variable goes out of scope.
Dynamically allocated array
An array whose size is decided at runtime, before creating the array.
numberOfAges = (some calculation);
int *ages = (int*) malloc(numberOfAges);
ages[0] = 1;
In this case, the size of the array isn't known at compile-time. It is decided at runtime, but once the array has been created, its size cannot change.
Advantage: You can make it different sizes depending on runtime requirements.
Disadvantage: You have to make your own code call free() to reclaim the storage.
Dynamic arrays
This is an array whose size grows or shrinks during its lifespan.
A hypothetical language might have statements like:
resize(ages, 5); // make "ages" 5 longer
truncate(ages, 3); // make "ages" 3 long, discarding later elements.
What your professor is saying, correctly, is that the core of C does not have arrays that can do this. A char* is a fixed size at the point it's allocated, and that can never change.
In C, if you want a list of values whose length grows or shrinks, you have to roll your own code to do it, or use a library of functions that provides it. Rather than working directly with arrays, you'd work with the API provided by the library. Indeed, it might look very much like the hypothetical example above, except that ages would not be an int* - it would be some type provided by the library.
#include <resizeableIntArrays.h>
...
ResizeableIntArray ages = allocateResizeableIntArray(100);
resize(ages,80);
There are lots of ways to achieve this - using realloc(), using linked lists or binary trees, using linked lists of arrays. I suspect when your professor is "evasive", he's really saving the more complicated stuff until later. Any respectable C course will get to this stuff eventually, but if ordinary arrays are new to you, it'll be a few weeks before you're ready for linked lists.
statically created arrays are those whose size u give as a constant during the declaration, like
int arr[10];
dynamically created arrays are those whose size is given as a variable. as variables can take any value during the array declaration, size depends on the variable value at that program instance, like
int n;
scanf("%d",&n);
int arr[n];
for your second question: dynamic arrays (arrays that change their size during program execution) do not exist in C. u can create a link list with dynamic memory allocation, which would be in essence a dynamic linear data structure (in contrast to a static linear data structure that array is).
Dynamically created array means array is created at run time. Either it would be a variable length arrays
int n = 5;
int a[n];
or created using malloc
int *a;
a = malloc(sizeof(int) * 5); // But note that pointers are not arrays
In C, there is no dynamic arrays. You can't add or delete new elements to it, i.e. once an array is created its size can't be changed.

Dynamic Array in C

Array by definition is a chunk of contiguous memory locations.
What i understand from Dynamic is that we can allocate memory at run time.
So for Dynamic Array lets say we allocate 100 memory spaces at run time. Now we perform some other operation and allocate few memory spaces for other variables.
Since the array we created was meant to be Dynamic so i suppose we can add more elements t it occupying more memory spaces.
But what i fail to understand is how this is going to be contiguous because the next memory addresses are per-occupied and Arrays by definition are supposed to be Contiguous???
You are mixing terminologies. In C and C++ arrays are technically a sequence of contiguous elements of the same type. When using the term "dynamic array" you are not using a standard-mandated term, but a general computer science term, which refers to array-like containers whose size can change at runtime.
In C++ these array-like containers are implemented, for example, through the vector class, available including the <vector> standard library header. In other languages there may be other facilities.
C has no dynamic arrays, but you can allocate arrays dynamically. Here the term "dynamic" has a different meaning: it is related to the management of dynamic memory, which is what you do when you use malloc and free functions.
In C++, dynamic arrays are implemented managing dynamic memory under the hood, but this is an implementation detail that has little to do with the terminology.
Also in C you could implement dynamic arrays (for example writing a custom library), but their usage wouldn't be supported by the language syntax, as in C++.
Whether or not the storage for a dynamic array (either in C++ or in C) is contiguous is, again, an implementation detail. If you need to have a dynamic array (general meaning) implemented as a C/C++ array (technical term), you will end up reallocating memory and copying elements around explicitly. The standard C library provides the realloc function to help coping with such a task.

Memory management in Lua

I am making a level editor for a simple game in lua and the tiles are represented by integers in a 2d array, when I read the level description in from a file, it may so happen that this 2d array is sparsely populated, how does lua manage memory ? will it kep those holes in the array or will it be smart about it and not waste any space?
The question itself is irrelevant in a practical sense. You have one of two cases:
Your tilemaps are reasonably small.
Your tilemaps are big enough such that compression is important for fitting in memory constraints.
If #1 is the case, then you shouldn't care. It doesn't matter how memory efficient Lua is or isn't, because your tilemaps aren't big enough for it to ever matter.
If #2 is the case, then you shouldn't care either. Why? Because if fitting in memory is important to you, and you're likely to run out, then you shouldn't leave it to the vagaries of how Lua happens to manage the memory for arrays.
If memory is important, you should build a specialized data structure that Lua can use, but is written in C. That way, you can have explicit control over memory management; your tilemaps will therefore take up as much or as little memory as you choose for them to.
As for the actual question, it rather depends on how you build your "array". Lua tables are associative arrays by nature, but their implementation is split between an "array part" and a "table part". In general though, if you store elements sparsely, then the elements will be sparsely stored in memory (for some definition of "sparse"). As long as you don't do something silly like:
for i = 1, max_table_size do
my_tilemap[i] = 0
end
Then again, you may want to do that for performance reasons. This ensures that you have a big array rather than a sparse table. Since the array elements are references rather than values, they only take up maybe 16 bytes per element. Once you decide to put something real in an entry (an actual tile), you can. Indexing into the array would be fast in this case, though since the table part is a hash-table, it's not exactly slow.

How can I concatenate two arrays in C?

How do I concatenate two arrays to get a single array containing the elements of both original arrays?
Arrays in C simply are a contiguous area of memory, with a pointer to their start*. So merging them involves:
Find the length of the arrays A and B, (you will probably need to know the number of elements and the sizeof each element)
Allocating (malloc) a new array C that is the size of A + B.
Copy (memcpy) the memory from A to C,
Copy the memory from B to C + the length of A (see 1).
You might want also to de-allocate (free) the memory of A and B.
Note that this is an expensive operation, but this is the basic theory. If you are using a library that provides some abstraction, you might be better off. If A and B are more complicated then a simple array (e.g. sorted arrays), you will need to do smarter copying then steps 3 and 4 (see: how do i merge two arrays having different values into one array).
Although for the purpose of this question, the pointer explanation will suffice, strictly speaking (and for pacifying the commenter below): C has the concept of an array, that can be used without the syntax of pointers. Implementation wise, however, a C array and a contiguous area of memory, with a pointer are close enough they can be, and often are, used interchangeably.

Resources