Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

push_back()/emplace_back() on array invalidates pointers to existing array items #1586

Closed
samwcoulter opened this issue Apr 27, 2019 · 2 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@samwcoulter
Copy link

I am serializing some internal structures to Json and would like to populate an array with null json values, storing a pointer to each null value and then later filling that value with the appropriate data. Eg:

    json arr = json::array();
    arr.emplace_back(nullptr);
    auto* ptr0 = &arr.at(0);
    arr.emplace_back(nullptr);
    auto* ptr1 = &arr.at(1);
    arr.emplace_back(nullptr);
    auto* ptr2 = &arr.at(2);
    //Some time later:
    *ptr0 = 0;
    *ptr1 = 1;
    *ptr2 = 2;

However, this apparently yields an array where the first two elements are null, and only the last element in the array contains the actual data (an integer == 2).

I am not sure if I am simply using the API incorrectly, or there is an actual issue that needs to be addressed. I would very much appreciate any help, thanks!

@nickaein
Copy link
Contributor

By default, JSON library uses std::vector data structure for storing JSON arrays. Therefore calling std::vector::emplace_back() or std::vector::push_back invalidates the iterators (and pointers in your case) when the capacity() is less or equal than size().

You can:

  1. Get reference to the items after emplace_back calls are done.
  2. Reserve the vector capacity beforehand. Since the JSON library API doesn't expose reserve(), you should first get a pointer/reference to the underlying std::vector and then call reserve() on it. This is discussed at resize(...)? #1157 and json array: initialize with prescribed size and resize method. #1057 for resize() method and you can adapt it for reserve().

@samwcoulter
Copy link
Author

The sized constructor from #1057 suited my needs perfectly, thank you.

@nlohmann nlohmann added kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation labels Apr 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

3 participants