3

What's the correct right hand side expression for initializing a storage array of address?

I'm trying to initialize a storage address[] from inside a function. Everything I've tried gives warnings, and I'm looking for the correct way to silence them.

// address[] storage b;
Warning: Uninitialized storage pointer.

This warning is warranted. After testing I've found b is pointing to "garbage data" which happens to be the same as another address[] storage a array I define earlier. (Related post) On top of that, modifying b (b.length = 0) is modifying the a array.

Every right hand expression I've tried hasn't worked, since they're meant for memory arrays. (eg. = address[]())

2

Although it doesn't directly address what you're asking, I think https://programtheblockchain.com/posts/2018/03/09/understanding-ethereum-smart-contract-storage/ will help.

When you just declare address[] storage b; (same as without storage, since that's the default), b points to slot 0 in storage, which will be whatever state variable you declared first.

Without knowing exactly what you're trying to do, it's hard to suggest a fix, but you probably want to use a mapping or array in the contract scope (e.g. mapping (uint256 => address[]) or the like).

  • 1
    Thanks for your answer. A workaround I've found is to move the declaration to the top, as a state variable. It's strange though, and I feel there must be a way to initialize it in a function. – Daniel Que Mar 13 '18 at 23:46
  • 1
    If you declared it in a function, how would you use it later? – user19510 Mar 14 '18 at 0:00
  • 1
    It's to test a library function which consumes a storage array. – Daniel Que Mar 14 '18 at 6:38
  • 1
    Ah, hopefully you can appreciate why that's a use case that's not worth optimizing for. Anyway, just use a mapping. E.g. index = 0; mapping (uint256 => address[]);. "Allocate" new dynamic arrays via address[] storage b = mapping[index++];. – user19510 Mar 14 '18 at 6:42
  • 2
    I've used something similar to "allocate" nodes for a linked list. You can also push onto a dynamically-sized array. – user19510 Mar 14 '18 at 6:50
1

The workaround I've found is to move the declaration to the top, as a state variable.

contract Test {
  address[] a;
  address[] b;

  function testFeature() {
    // test
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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