associative arrays

Jonathan M Davis jmdavisProg at gmx.com
Sun Jan 8 04:49:33 PST 2012


On Sunday, January 08, 2012 13:06:06 simendsjo wrote:
> Certainly not obvious to me :)

Well, what's obvious to one person is not always obvious to another. I'm sure 
that there are plenty of things that Walter thinks should be perfectly obvious 
which 90% of programmers would never think of. A lot of it depends on what 
you're experience level is and what you have experience in. In this case, it's 
very much like dealing with C++ iterators, so if you're used to dealing with 
them and when they do or don't get invalidate, then the situation with in and 
remove is probably quite straightforward and intuitive.

> auto c = new C();
> C[string] aa;
> aa["c"] = c;
> aa.remove("c");
> 
> I guess using c from this point is valid, but if the only reference to c
> was inside the aa (and we got c using `in`), using c would have been
> undefined..?

Using c is valid regardless. The problem is the in operator. It returns a 
pointer to the element inside of the AA. So, if you did

C* d = aa["c"];

then d would be a pointer to a reference to a C, and after the call to remove, 
the pointer is pointing to memory which may or may not be part of the AA 
anymore and which may or may not hold a reference to what c refers to. It's 
bit like doing this

int* a()
{
    int b;
    return &b;
}

though the compiler should catch this, since it's obviously wrong. In both 
cases, you're referring to memory which your really not supposed to be 
accessing anymore and may point to invalid memory. The case of the AA probably 
isn't as bad, since either you're pointing to memory on the GC which isn't 
part of the AA (but hasn't been collected, since you have a pointer to it), or 
you're pointing to an element in the AA which may still be the same as it was 
before it was removed, or it may be another element, or it may be garbage 
memory. You really don't know. It's undefined and therefore shouldn't be used.

I don't believe that it's ever safe to assume that the pointer returned by the 
in operator is still valid after the AA that it comes from has had an element 
added or removed. It's the same with iterators or ranges with many iterators 
and ranges. If they point to elements within a container, and that container 
is altered, they're invalidated and aren't safe to use.

So, your example is fine, because it doesn't involve the in operator, and 
therefore doesn't involve any pointers into the AA. It's only once you have 
pointers into the AA that you get into trouble.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list