associative arrays

simendsjo simendsjo at gmail.com
Sun Jan 8 05:24:32 PST 2012


On 08.01.2012 13:49, Jonathan M Davis wrote:
> 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

Thanks for your clarifications.

Does this mean even this is undefined?
aa["a"] = new C();
auto c = "a" in aa;
aa["b"] = new C();
// Using c here is undefined as an element was added to aa


More information about the Digitalmars-d-learn mailing list