pragma solidity ^0.4.0;
contract TestcaseResetObject {

    MyObject ob;

    struct MyObject {
        mapping(uint8 => uint) map;
    }

    event Output(uint number);

    function makeNew() {
        ob = MyObject();
        ob.map[0] += 1;
        Output(ob.map[0]);
    }
}

When I run makeNew repeatedly in browser-solidity, I'm expecting to get every time the event Output(1). Instead, I get Output(1), Output(2), Output(3), etc.

It seems when I create a new MyObject, the map isn't actually created again.

Another question relates that freshly initialized struct should have a "zero" value in all its members. This seems true for uint's etc. but since mapping seems to "remember" its old values this seems not to be the case.

Any ideas?

up vote 2 down vote accepted

Agree with Guiseppe. The code isn't "initializing" new ob, just referencing existing.

Here's a way to have many mappings that don't collide like that. Possibly will give you some ideas.

pragma solidity ^0.4.0;
contract TestcaseResetObject {

    uint public objectCount;

    struct MyObjectStruct {
        mapping(uint => uint) map;
    }

    MyObjectStruct[] myObjects;

    event LogOutput(uint number);

    function makeNewObject() public returns(uint count) {

        MyObjectStruct memory mo;
        objectCount = myObjects.push(mo);
        return objectCount;
    }

    // object numbers start at 0 when objectCount is 1
    function incCounter(uint objectNumber, uint index) public returns(uint newValue) {
        myObjects[objectNumber].map[index] += 1;
        LogOutput(myObjects[objectNumber].map[index]);
        return myObjects[objectNumber].map[index];
    }
}

Let's you "makeNewObject" to create new mappings, and "incCounter" to single out a specific mapping from the array, and a specific location inside the mapping to increment.

Hope it helps.

  • Modified the code just a little bit (formatting), hand-tested in remix so it works. – Juuso Jan 17 at 9:11

Mapping is a really particular type and it's different from a simple array. From the official documentation:

Mappings can be seen as hashtables which are virtually initialized such that every possible key exists and is mapped to a value whose byte-representation is all zeros: a type’s default value. The similarity ends here, though: The key data is not actually stored in a mapping, only its keccak256 hash used to look up the value.

Because of this, mappings do not have a length or a concept of a key or value being “set”.

This means essentially that you don't really ever initialize a full mapping variable (in your case, using MyObject() you initialize the ob struct, not the map variable).

The second time you refer to map[0] it correctly points to the same position as before, and so you find the old value.

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.