I have the following mapping(uint => Foo[]) data structure. I have mapped 10 unique ids with 10 Foo structs, where each Foo is an arraylist of 10 items.

Step 1:

for(int i = 0; i < 10; i++)
   for(int j = 0; j < 10; j++)
       add(i, j); 

Step 2: I delete the items pushed before. I'm not sure which one is the correct approach among a) and b) below. Approach b) leaves holes by only resetting the members in the struct

a)  for(int i = 0; i < 10; i++)      | b) for(int i = 0; i < 10; i++)
           delete(i);                |      for(int j = 0; j < 10; j++)
                                     |          delete_items(i, j)  

Step 3: I push new items with different mapping uint id.

for(int i = 20; i < 30; i++)
   for(int j = 20; j < 30; j++)
       add(i, y); 

[Q] Would delete mapping_array[id] actually free the memory that was allocated by the array list within the mapping? Or would it only zero out the memory as if delete was used on Array List, and the item remains in the mapping as empty, but still taking memory space?

[Q] In total, I have mapped 10 unique ids with 10 Foo structs, where each Foo is an arraylist of 10 items. Later I delete the items in my mapping data structure then insert new items into it. So would the newly inserted items get new memory allocated for them, or would they be overwritten in memory of recently deleted items?

These matter because I am using a mapping data structure of very large size and items get inserted and removed frequently. I know delete won’t free memory on an Array, but not sure if it’s the same in mapping.

I am using the following code piece from this question's answer: https://ethereum.stackexchange.com/a/1458/4575

  struct Foo{
    uint x;
  }
  mapping(uint => Foo[]) mapping_array;

  function add(uint id, uint _x) public {
    mapping_array[id].push(Foo(_x));
  }

  function get(uint id, uint index) public returns(uint){
    return mapping_array[id][index].x;
  }

  function delete_(uint id) public {
    delete mapping_array[id];
  }

  function delete_items(uint id, uint index) public {
    delete mapping_array[id][index];
  }

Delete:

delete a assigns the initial value for the type to a. I.e. for integers it is equivalent to a = 0, For structs, it assigns a struct with all members reset.

delete has no effect on whole mappings (as the keys of mappings may be arbitrary and are generally unknown). So if you delete a struct, it will reset all members that are not mappings and also recurse into the members unless they are mappings. However, individual keys and what they map to can be deleted.

It is important to delete a really behaves like an assignment to a, i.e. it stores a new object in a.

Link: http://solidity.readthedocs.io/en/develop/types.html

Thank you for your valuable time and help.

  • try to debug the code and you will get the answer – Badr Bellaj Oct 25 '16 at 12:24
  • I did but how could I understand that memory is freed? – alper Oct 27 '16 at 12:14
  • After all insert operations are done for example: delete mapping_array[0]; removes the mapping and when I try to call mapping_array[0][index].data Solidity gives and error. So it removes the mapping, should I assume (or trust to Solidity) that memory is also freed? – alper Oct 27 '16 at 12:24
  • @BadrBellaj please see my question again, I have extended it. – alper Oct 27 '16 at 13:28
up vote 2 down vote accepted

Based on my Debug observation:

I have tested that:

  • Firstly I insert data into my map data-structure as I explained in my question.
  • Secondly, I have returned the address of first mapped index, which is 0, this could be done for other indexes as well (0:10).
  • Without a delete operation I can retrieve the data perfectly fine from the address of mapped Foo[]. But if I did the delete operation, Solidity gives an error.

This debug result: leads me to conclude that memory is freed or address does not contain any valid information.

Test code:

set_txn_hash     = my_contract.transact().map_insert();
contract_address = unmigrated_chain.wait.for_receipt(set_txn_hash)

for x in range(0, 9):
   for y in range(0, 9):
         output           = my_contract.call().get_(x, y);
         print(output);  //returns correct value.

set_txn_hash     = my_contract.transact().map_remove_map();                                             
contract_address = unmigrated_chain.wait.for_receipt(set_txn_hash)                                      

set_txn_hash     = my_contract.transact().get_map_address(0);
contract_address = unmigrated_chain.wait.for_receipt(set_txn_hash)

output           = my_contract.call().get_map();
print(output);

output           = my_contract.call().try_();
print(output);  //Solidity gives error if delete map_remove_map() is called

Additional functions inside my Contract:

  function map_insert(){
    for(uint i = 0; i < 10; i++)
      for(uint j = 0; j < 10; j++)
        add(i, i*10 + j);
  }

  function map_remove_map(){
    for(uint i = 0; i < 10; i++)
      delete_(i);
  }

  function map_remove_map_item(){
    for(uint i = 0; i < 10; i++)
      for(uint j = 0; j < 10; j++)
        delete_items(i, j);
  }

  function get_map_address(uint id) {
    uint addr;
    Foo[] a = foo[id];

    assembly{
    addr := a
        }
    map_address = addr;
  }

  function get_map() constant returns (uint){
    return map_address;
  }

  function try_() constant returns (uint ){
    uint addr = map_address;
    Foo[] a;
    assembly{
    a := addr
        }
    return a[1].x;  
  }
  • If I understand it correctly, those results contradict what is written in the documentation. Any idea how come? – David Ammouial Jun 12 '17 at 21:48
  • Pushed memory never be deleted since it memory is very expensive for all thousands nodes to remove it that there might be in the holes in the array. So as a easy solution as I understand, they just make memory equal to zero. Are you referring into Solidity Doc? @DavidAmmouial – alper Jun 13 '17 at 1:32

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.