Thread overview
Associative array on the heap
May 18, 2015
Freddy
May 19, 2015
Meta
May 19, 2015
Meta
May 19, 2015
Freddy
May 19, 2015
Xinok
May 19, 2015
ketmar
Jul 07, 2020
mw
May 18, 2015
How do you allocate an associative array on the heap?
----
void main(){
	alias A=int[string];
	auto b=new A;
}
----
$ rdmd test
test.d(4): Error: new can only create structs, dynamic arrays or class objects, not int[string]'s
Failed: ["dmd", "-v", "-o-", "test.d", "-I."]
May 19, 2015
On Monday, 18 May 2015 at 23:55:40 UTC, Freddy wrote:
> How do you allocate an associative array on the heap?
> ----
> void main(){
> 	alias A=int[string];
> 	auto b=new A;
> }
> ----
> $ rdmd test
> test.d(4): Error: new can only create structs, dynamic arrays or class objects, not int[string]'s
> Failed: ["dmd", "-v", "-o-", "test.d", "-I."]

They are allocated on the heap implicitly; there's no need for `new`. You actually *can't* use new with an AA, which is what the compiler is telling you.

void main()
{
    alias A = int[string];
    A b = []; //No allocation yet, b is null
    b["test"] = 1; //b is now non-null
}
May 19, 2015
On Tuesday, 19 May 2015 at 00:00:30 UTC, Meta wrote:
>     A b = []; //No allocation yet, b is null

Whoops, you actually can't assign the empty array literal to an AA. This line should be:

A b;

Which has the exact same effects.

May 19, 2015
On Mon, 18 May 2015 23:55:38 +0000, Freddy wrote:

> How do you allocate an associative array on the heap?
> ----
> void main(){
> 	alias A=int[string];
> 	auto b=new A;
> }
> ----
> $ rdmd test test.d(4): Error: new can only create structs, dynamic arrays or class objects, not int[string]'s Failed: ["dmd", "-v", "-o-", "test.d", "-I."]

AAs are always allocated on heap, you don't need to do anything special.

May 19, 2015
On Tuesday, 19 May 2015 at 00:00:30 UTC, Meta wrote:
> On Monday, 18 May 2015 at 23:55:40 UTC, Freddy wrote:
>> How do you allocate an associative array on the heap?
>> ----
>> void main(){
>> 	alias A=int[string];
>> 	auto b=new A;
>> }
>> ----
>> $ rdmd test
>> test.d(4): Error: new can only create structs, dynamic arrays or class objects, not int[string]'s
>> Failed: ["dmd", "-v", "-o-", "test.d", "-I."]
>
> They are allocated on the heap implicitly; there's no need for `new`. You actually *can't* use new with an AA, which is what the compiler is telling you.
>
> void main()
> {
>     alias A = int[string];
>     A b = []; //No allocation yet, b is null
>     b["test"] = 1; //b is now non-null
> }

Sorry mis-phrased my question,
 Who do you allocate a pointer to an associative array(int[string]*).
May 19, 2015
On Tuesday, 19 May 2015 at 00:31:50 UTC, Freddy wrote:
> Sorry mis-phrased my question,
>  Who do you allocate a pointer to an associative array(int[string]*).

Ignoring the why for a moment, one trick is to place it in an array literal so it's heap allocated. This requires writing an associative array literal with a single key-element pair though.

int[string]* a = [["zero":0]].ptr;


Another trick is to initially define the associative array in a class. Since classes are heap allocated, you can allocate an instance of the class and grab a pointer to the associative array.

class HeapAA
{
    int[string] a;
}

int[string]*b = &(new HeapAA).a;
May 19, 2015
On 5/18/15 7:55 PM, Freddy wrote:
> How do you allocate an associative array on the heap?
> ----
> void main(){
>      alias A=int[string];
>      auto b=new A;
> }
> ----
> $ rdmd test
> test.d(4): Error: new can only create structs, dynamic arrays or class
> objects, not int[string]'s
> Failed: ["dmd", "-v", "-o-", "test.d", "-I."]

As others have said, I don't know why you would want to do this, since AA is already simply a wrapper for a pointer to a heap-allocated AA.

But if you wanted to, you could put it in a struct:

struct AA
{
   int[string] x;
}

void main()
{
   auto b = &((new AA).x);
}

-Steve
July 07, 2020
On Tuesday, 19 May 2015 at 12:21:48 UTC, Steven Schveighoffer wrote:
> On 5/18/15 7:55 PM, Freddy wrote:
>> How do you allocate an associative array on the heap?
>> ----
>> void main(){
>>      alias A=int[string];
>>      auto b=new A;
>> }
>> ----
>> $ rdmd test
>> test.d(4): Error: new can only create structs, dynamic arrays or class
>> objects, not int[string]'s
>> Failed: ["dmd", "-v", "-o-", "test.d", "-I."]
>
> As others have said, I don't know why you would want to do this, since AA is already simply a wrapper for a pointer to a

AA is a wrapper for a pointer (e.g a struct with some extra info beyond the plain pointer), or AA is just the plain pointer (nothing extra)?

I tried this:

  class Foo {}
  Foo[string] foos;
  writeln(foos.sizeof);  // print 8

looks like it's just a plain pointer?


The usage pattern to have AA on the heap is, e.g:

class Class {
  StudentInfo[string] students;  // dict-by-name
  // many other fields
}

suppose in a multi-threaded app, the Class object is shared, and one thread will perform a lengthy updates on all the students. To ensure data consistency among all the students object, instead of updating each student's info of the original AA in a loop (with lengthy locking period), it can be achieved by heap-alloc a new AA, update the new AA, and atomic-set:

  new_students = new StudentInfo[string];  // heap-alloc a new AA
  // length update on each of new_students
  atomicStore(theClass.students, new_students);


July 07, 2020
On 7/7/20 3:08 AM, mw wrote:
> On Tuesday, 19 May 2015 at 12:21:48 UTC, Steven Schveighoffer wrote:
>> On 5/18/15 7:55 PM, Freddy wrote:
>>> How do you allocate an associative array on the heap?
>>> ----
>>> void main(){
>>>      alias A=int[string];
>>>      auto b=new A;
>>> }
>>> ----
>>> $ rdmd test
>>> test.d(4): Error: new can only create structs, dynamic arrays or class
>>> objects, not int[string]'s
>>> Failed: ["dmd", "-v", "-o-", "test.d", "-I."]
>>
>> As others have said, I don't know why you would want to do this, since AA is already simply a wrapper for a pointer to a
> 
> AA is a wrapper for a pointer (e.g a struct with some extra info beyond the plain pointer), or AA is just the plain pointer (nothing extra)?

AA is a pImpl type wrapper. Yes, it's just a pointer inside.

But it's not simply a pointer because things like indexing can change the pointer (i.e. if the pointer is null, it will allocate a new AA impl).

If it were just a pointer, then using it without initializing would be a segfault.

-Steve