GCC 4.0 Ada.Containers Cursor danger.



IMHO the cursors in the Ada.Containers implemented in GCC 4.0
dangerouse like pointers in C/C++.

Look at the code below.
----------------------------------------------
with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;

package HTab is new Ada.Containers.Indefinite_Hashed_Maps
(String, Integer, Ada.Strings.Hash, "=", "=");
-----------------------------------------------------------------
with Ada.Text_IO;
with HTab;

procedure AC1 is
use Ada.Text_IO;

package Table renames HTab;

Cursor : Table.Cursor;
Cursor2 : Table.Cursor;
Container : Table.Map;
Success : Boolean;
begin
Table.Insert (Container, "one", 11111, Cursor, Success);
pragma Assert (Success);
Table.Insert (Container, "two", 22222, Cursor, Success);
pragma Assert (Success);
Table.Insert (Container, "three", 33333, Cursor, Success);
pragma Assert (Success);

Table.Insert (Container, "two", 2222, Cursor, Success);
pragma Assert (not Success);

-- Delete element "two" independently.

Cursor2 := Table.Find (Container, "two");
Table.Delete (Container, Cursor2);

-- The erroreneous line below do nothing and do not raise any
exception.

Table.Replace_Element (Cursor, -22222);

Cursor := Table.First (Container);

-- Print all lines, and see that we do not have a key "two".

while Table.Has_Element (Cursor) loop
Put_Line (Table.Key (Cursor) & ' ' & Integer'Image (Table.Element
(Cursor)));
Table.Next (Cursor);
end loop;
end AC1;
------------------------------------------------------------
The code above have to raise at least runtime error at
Table.Replace_Element (Cursor, -22222); but it do nothing and do not
raise any exception.

valgrind showing the memory corruption
---------------------------
==24602== Invalid read of size 4
==24602== at 0x804F1EC: htab__replace_element (a-cihama.adb:630)
==24602== by 0x805024D: _ada_ac1 (ac1.adb:31)
==24602== by 0x8049C2F: main (b~ac1.adb:157)
==24602== Address 0x1BA4EAF8 is 8 bytes inside a block of size 16
free'd
==24602== at 0x1B903B0D: free (vg_replace_malloc.c:152)
==24602== by 0x805D257: __gnat_free (s-memory.adb:113)
==24602== by 0x804D8CD: htab(float, long double,...)(...)
(a-cihama.adb:338)
==24602== by 0x804CAE5: htab__delete__2 (a-cihama.adb:205)
==24602== by 0x805021E: _ada_ac1 (ac1.adb:27)
==24602== by 0x8049C2F: main (b~ac1.adb:157)
==24602==
==24602== Invalid write of size 4
==24602== at 0x804F223: htab__replace_element (a-cihama.adb:632)
==24602== by 0x805024D: _ada_ac1 (ac1.adb:31)
==24602== by 0x8049C2F: main (b~ac1.adb:157)
==24602== Address 0x1BA4EAF8 is 8 bytes inside a block of size 16
free'd
==24602== at 0x1B903B0D: free (vg_replace_malloc.c:152)
==24602== by 0x805D257: __gnat_free (s-memory.adb:113)
==24602== by 0x804D8CD: htab(float, long double,...)(...)
(a-cihama.adb:338)
==24602== by 0x804CAE5: htab__delete__2 (a-cihama.adb:205)
==24602== by 0x805021E: _ada_ac1 (ac1.adb:27)
==24602== by 0x8049C2F: main (b~ac1.adb:157)
---------------------------

I am using "ADT Components" from
http://lgl.epfl.ch/ada/components/index.html too.
I'm writting in ADT but have to use code with AI302.
I did not found so much errors with ADT as with AI302 and with
Ada.Containers cursors.

ADT do not have a cursors at all. All get/put operations from container
is just per key. All iterations via the containers are with simple
generic procedures.

I'm not sure that it is possible to implement runtime error detection
in such cursor situation.

I think that ADT is much more on the Ada way then proposed
Ada.Containers with cursors.

.



Relevant Pages