[Ethereum] Mapping member isn’t initialized when creating a struct

constructormappingremixsoliditystruct

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?

Best Answer

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.

Related Topic