How is an array of object[]s stored in memory? - arrays

As I understand it, the elements of an array are stored contiguously in memory, and accessing a particular one it is done by adding the product of the desired index and the size of each element with the base array address to find the address of the element.
Since in a language like C# I can create an array of object[]s and put whatever data type I want in it, how is each element of the array stored (and kept) at a uniform length if I used differently sized types while still allowing for random access?

This depends on the language in question, and what you mean by "object" -
As you mentioned C#, in C# (.NET), an object[] contains an array of references to individual object instances. The array is an array of references - the object instance still needs to be assigned to an element of the array. The references are of a uniform size, but the object instances themselves are stored separately, and do not have to be the same size.
This is the same in most languages when storing an array of "references" or "pointers", and not the object instances themselves.

Objects are reference types. The value at the address is actually a pointer to the true element.

Related

Difference between list and arrays

Are lists and arrays different in python?
Many articles refer to the following as an array: ar = [0]*N of N element. Which is a list. Not sure if these words are used interchangeably in python. And then there is a module called array
The terms "list" and "array" are not interchangeable in either Python or computer science (CS).
In CS an array data structure is defined, as you've already noted, as a contiguous block of data elements all of which are the same size. Python's list does not conform to this definition as each element of a Python list can not only be a completely different data type, but can even be another data structure type such as list, dictionary, or set.
Python stores each element of a list as a separate data object, and the references to those objects are stored in Python's list data type. My past reading indicates that the list is stored as an array, but I've measured the list's time complexity and I suspect that it may technically be a hash table.
Python's lists may be ordered, and you can use and access a Python list as if it were an array as I frequently do, but don't be confused by Python's use of square brackets: it's not an array.
Python's array module implements an actual array data type for storing numerical data (actually, I think you can store character data as well).

How do I create array with dynamic length rather than slice in golang?

For example: I want to use reflect to get a slice's data as an array to manipulate it.
func inject(data []int) {
sh := (*reflect.SliceHeader)(unsafe.Pointer(&data))
dh := (*[len(data)]int)(unsafe.Pointer(sh.Data))
printf("%v\n", dh)
}
This function will emit a compile error for len(data) is not a constant. How should I fix it?
To add to the #icza's comment, you can easily extract the underlying array by using &data[0]—assuming data is an initialized slice. IOW, there's no need to jump through the hoops here: the address of the first slice's element is actually the address of the first slot in the slice's underlying array—no magic here.
Since taking an address of an element of an array is creating
a reference to that memory—as long as the garbage collector is
concerned—you can safely let the slice itself go out of scope
without the fear of that array's memory becoming inaccessible.
The only thing which you can't really do with the resulting
pointer is passing around the result of dereferencing it.
That's simply because arrays in Go have their length encoded in
their type, so you'll be unable to create a function to accept
such array—because you do not know the array's length in advance.
Now please stop and think.
After extracting the backing array from a slice, you have
a pointer to the array's memory.
To sensibly carry it around, you'll also need to carry around
the array's length… but this is precisely what slices do:
they pack the address of a backing array with the length of the
data in it (and also the capacity).
Hence really I think you should reconsider your problem
as from where I stand I'm inclined to think it's a non-problem
to begin with.
There are cases where wielding pointers to the backing arrays
extracted from slices may help: for instance, when "pooling"
such arrays (say, via sync.Pool) to reduce memory churn
in certain situations, but these are concrete problems.
If you have a concrete problem, please explain it,
not your attempted solution to it—what #Flimzy said.
Update I think I should may be better explain the
you can't really do with the resulting
pointer is passing around the result of dereferencing it.
bit.
A crucial point about arrays in Go (as opposed to slices)
is that arrays—as everything in Go—are passed around
by value, and for arrays that means their data is copied.
That is, if you have
var a, b [8 * 1024 * 1024]byte
...
b = a
the statement b = a would really copy 8 MiB of data.
The same obviously applies to arguments of functions.
Slices sidestep this problem by holding a pointer
to the underlying (backing) array. So a slice value
is a little struct type containing
a pointer and two integers.
Hence copying it is really cheap but "in exchange" it
has reference semantics: both the original value and
its copy point to the same backing array—that is,
reference the same data.
I really advise you to read these two pieces,
in the indicated order:
https://blog.golang.org/go-slices-usage-and-internals
https://blog.golang.org/slices

Data structure - Array

Here it says:
Arrays are useful mostly because the element indices can be computed
at run time. Among other things, this feature allows a single
iterative statement to process arbitrarily many elements of an array.
For that reason, the elements of an array data structure are required
to have the same size and should use the same data representation.
Is this still true for modern languages?
For example, Java, you can have an array of Objects or Strings, right? Each object or string can have different length. Do I misunderstand the above quote, or languages like Java implements Array differently? How?
In java all types except primitives are referenced types meaning they are a pointer to some memory location manipulated by JVM.
But there are mainly two types of programming languages, fixed-typed like Java and C++ and dynamically-typed like python and PHP. In fixed-typed languages your array should consist of the same types whether String, Object or ...
but in dynamically-typed ones there's a bit more abstraction and you can have different data types in array (I don't know the actual implementation though).
An array is a regular arrangement of data in memory. Think of an array of soldiers, all in a line, with exactly equal spacing between each man.
So they can be indexed by lookup from a base address. But all items have to be the same size. So if they are not, you store pointers or references to make them the same size. All languages use that underlying structure, except for what are sometimes called "associative arrays", indexed by key (strings usually), where you have what is called a hash table. Essentially the hash function converts the key into an array index, with a fix-up to resolve collisions.

How can I create an Array from an UnsafeBufferPointer without copying?

I'm in a tricky situation where I have a very large memory represented by an UnsafeBufferPointer, and I need to represent it as an Array. Now, the Swift standard library offers an initializer that copies elements from any given sequence, however it offers no way to directly provide the underlying storage.
Is there any way I can 'cast' an UnsafeBufferPointer to an Array while avoiding copying?
struct UnsafeBufferPointer<Element> { ... }
A non-owning pointer to buffer of Elements stored contiguously in
memory, presenting a Collection interface to the underlying elements.
The answer is no, it is impossible.
init(start: UnsafePointer<Element>, count: Int)
Construct an UnsafePointer over the count contiguous Element instances
beginning at start.
The constructor doesn't copy anything anywhere. The constructor doesn't create any memory allocation

filter an array on the basis of some property of the objects of array

I have an array with some objects stored in it.
Say I have objects of type application.
Each application object has some information associated with it like applicationType, appId etc.
I need to create seperate arrays for each applicationType.
like everytime I need to fetch out the objects of same applicationType.
i.e at the end i need to have an array that will consist of objects ( that will be arrays of same applicationType)
eg : object at 0th index will be an array of application of applicationType1.
object at 1st index will be an array of application of applicationType 2.
etc....
What is the most efficient way to do this ?
You create the array-of-arrays, then iterate over your original array of objects, find out the type of each & add it to the appropriate array in your array-of-arrays, creating a new one each time you encounter a type for the first time. You'll need a mapping from types to indices in your array-of-arrays; a map (or dictionary) would be good for that. In fact, if you have the flexibility, I'd make the array-of-arrays a map/dictionary and cut out the middleman.

Resources