У меня есть следующая 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
Спасибо за ваше драгоценное время и помощь.
Основываясь на моем наблюдении отладки:
Я проверил это:
Этот результат отладки: приводит меня к выводу, что память освобождена или адрес не содержит достоверной информации.
Тестовый код:
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;
}
Бадр Беллай
альпер
альпер
альпер