Действительно ли «удаление» при отображении освобождает место в памяти?

У меня есть следующая mapping(uint => Foo[])структура данных. Я сопоставил 10 уникальных идентификаторов с 10 структурами Foo, где каждый Foo является массивом из 10 элементов.

Шаг 1:

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

Шаг 2: Я удаляю элементы, отправленные ранее. Я не уверен, какой из вариантов а) и б) ниже является правильным. Подход b) оставляет дыры, только сбрасывая элементы в структуре

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)  

Шаг 3: Я отправляю новые элементы с другим идентификатором сопоставления uint.

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

[В] Действительно ли delete mapping_array[id]освободится память, выделенная списком массивов в mapping? Или это только обнуляет память, как если бы deleteона использовалась в списке массивов, а элемент остается mappingпустым, но все еще занимает место в памяти?

[В] В общей сложности я сопоставил 10 уникальных идентификаторов с 10 структурами Foo, где каждая Foo является массивом из 10 элементов. Позже я удаляю элементы в своей mappingструктуре данных, а затем вставляю в нее новые элементы. Получат ли вновь вставленные элементы новую память, выделенную для них, или они будут перезаписаны в памяти недавно удаленных элементов?

Это важно, потому что я использую структуру данных сопоставления очень большого размера, а элементы часто вставляются и удаляются. Я знаю, что удаление не освободит память в массиве, но не уверен, что это то же самое при отображении.

Я использую следующий фрагмент кода из ответа на этот вопрос: 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 a присваивает начальное значение типа a. Т.е. для целых чисел это эквивалентно a = 0. Для структур оно присваивает структуру со сбросом всех членов.

delete не влияет на сопоставления целиком (поскольку ключи сопоставлений могут быть произвольными и, как правило, неизвестными). Поэтому, если вы удалите структуру, она сбросит все члены, которые не являются сопоставлениями, а также рекурсивно перейдет к членам, если они не являются сопоставлениями. Однако отдельные ключи и то, на что они сопоставляются, можно удалить.

Важно, что удаление a действительно ведет себя как присваивание a, т.е. оно сохраняет новый объект в a.

Ссылка: http://solidity.readthedocs.io/en/develop/types.html

Спасибо за ваше драгоценное время и помощь.

попробуй отладить код и получишь ответ
Я сделал, но как я мог понять, что память освобождена?
После выполнения всех операций вставки, например: delete mapping_array[0]; убирает сопоставление и при попытке вызвать mapping_array[0][index].data Solidity выдает и ошибку. Таким образом, это удаляет сопоставление, должен ли я предполагать (или доверять Solidity), что память также освобождается?
@BadrBellaj, пожалуйста, посмотрите мой вопрос еще раз, я расширил его.

Ответы (1)

Основываясь на моем наблюдении отладки:

Я проверил это:

  • Во-первых, я вставляю данные в свою структуру данных карты, как я объяснил в своем вопросе.
  • Во-вторых, я вернул адрес первого сопоставленного индекса, который равен 0, это можно сделать и для других индексов (0:10).
  • Без операции удаления я могу отлично получить данные с адреса сопоставленного Foo[]. Но если я сделал операцию удаления, Solidity выдает ошибку.

Этот результат отладки: приводит меня к выводу, что память освобождена или адрес не содержит достоверной информации.

Тестовый код:

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

Дополнительные функции внутри моего Контракта:

  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;  
  }
Если я правильно понимаю, то эти результаты противоречат тому, что написано в документации. Любая идея, почему?
Выталкиваемая память никогда не удаляется, так как память очень дорогая для всех тысяч узлов, чтобы удалить ее, что может быть в дырах в массиве. Так что в качестве простого решения, насколько я понимаю, они просто делают память равной нулю. Вы имеете в виду Solidity Doc? @DavidAmmouial