unordered_map bugging out when assigning or inserting [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Whenever I try to initialise/assign or insert a lot of elements at once it won't insert the items and then will skip the rest of the function.
My map is of types int and a struct that holds 6 const char*'s, there are ~70 elements that I want to initialise my map with. Ive tried using less elements (~50) but it still bugs out.
Ive tried debugging it line by line and it will run for the first ~20 elements then after that it will start skipping them, e.g. insert(elem_20) then will skip to insert(elem_22) and {pair20, pair21, pair22} would skip pair21 and go straight to pair22, it seems random as far as I can tell.
I have tried the following :
// global scope, won't initialise the map
unordered_map<int, struct> my_map = {std::make_pair(...), ...};
// in a function
void init_map()
{
// my_map is defined in the global scope
// won't be assigned
my_map = { std::make_pair(...), ... };
// this will be skipped
other_func();
...
}
// in a function
void init_map_insert()
{
// will insert the first 20 or so then gets buggy after that
// my_map is defined in the global scope
my_map.insert(std::make_pair(...));
my_map.insert(std::make_pair(...));
my_map.insert(std::make_pair(...));
...
// this will be skipped
other_func();
...
}
Video of the problem : https://www.youtube.com/watch?v=pIg6bn6fB6E
You can see the first breakpoint getting triggered but then the breakpoints at the end of the of the function aren't triggered, as well as the breakpoint right after the function call.
I am using Xcode on MacOS 10.14.
Any help would be appreciated
Cheers
Edit : sorry, I'm not that good at explaining
Edit 2 : Added video

I'm going to leave this as an answer even though it shouldn't be because you didn't provide any reproducible code or enough information so I can only guess here. When using a map of any kind, including of course unordered_map, it will only allow one entry per key. You did not specify how your key is determined but my guess is that you have cases where a new value is entered but overwrites an existing key.

Your unordered_map is initialized here:
unordered_map<int, struct> my_map = {std::make_pair(...), ...};
then you re-initialized the map in init_map(), which wipes out the what was previously initialized in the list initialization.
// in a function
void init_map()
{
// my_map is defined in the global scope
// won't be assigned
my_map = { std::make_pair(...), ... };
Note that my_map = { blah } is equivalent to
my_map = unordered_map<int, struct>{blah}
which invokes assignment operator of my_map.
This is probably the bug you're talking about.

Related

global scoped variables in c++ not properly initialized [duplicate]

This question already has answers here:
Prevent static initialization order "fiasco", C++
(3 answers)
c++ static initialization order fiasco
(2 answers)
Is the "static initialization order fiasco" a concern for constexpr variables?
(1 answer)
Closed 2 years ago.
I ported my code from stm32f072 to stm32f105. Since then I have an issue with global variables, it seems they don't get initialized. I use Atollic TrueStudio and their compile and build tools. For the new platform I tried converting the existing "eclipse" project and also to create a new one from CubeMx.
I got a Hardfault when accessing a global object. The "workaround" was moving the new statement in the accessing function. The debugger showed that even when having the new statement the global var was 0x00.
I also use an std::queue which has an size() of 0xffffffe7 when not inserted anything yet, which let me believe this also comes from a missing initialization.
I want to solve the issue, not move all init in the beginning of the main function as a workaround.
My code looks something like this:
#include <queue>
std::queue<Telegram> telegram_in_fifo;
Port *port1 = new IoPort(/* some args */);
void some_function() { // tried calling from Interrupt or from main
// port1 is 0x00 here
port1 = new IoPort(/* some args */);
// now port1 has proper address and accessing internal data works without hardfaults
uint64_t size = telegram_in_fifo.size(); // this is 0xffffffe7
if(size <= fifo_max) {
telegram_in_fifo.push(telegram);
}
}

c++ attempting to reference a deleted function in non existing constructor (using rapidJson) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm currently getting this error:
'User::User(const User&)': attempting to reference a deleted function
The program passes a string value of an object into the class.
User Constructor:
User::User(string s){
int size = s.length() + 1;
char* cstr = new char[size];
strcpy_s(cstr, size, s.c_str());
user.Parse(cstr);
}
Main Loop:
int main(){
//json equals something similar to this: "{\"body:{[{"user":1},{"user":1},{"user":1}]}\"}";
const char * json;
Document d;
d.Parse(json);
if (d.HasMember("body")) {
if (d["body"].IsArray()) {
for (SizeType i = 0; i < d["body"].Size(); i++) {
string json = getJsonString(d["body"][i]);
User u = User(json); \\this is where the error point to
this->users.push_back(u);
}
}
}
}
getJsonString function:
string getJsonString(Value& value) {
StringBuffer buffer;
buffer.Clear();
Writer<StringBuffer> writer(buffer);
value.Accept(writer);
return string(buffer.GetString());
}
I search for a lot of explanation on this error but nothing seems to make sense to me. I think it has something to do with the vector array however it doesn't make sense to me as I'm not using a pointer or reference for any of the user value. It seems to point to the constructor however no pointer or reference is being passed through. I through by returning the string of the json, I wasn't using a pointer but maybe I actually am? I would be grateful for any explanation to what I am doing wrong.
User is not copyable; this means that:
User::User(const User&) (copy constructor) is private
or deleted (= delete;)
or deleted implicitly (e.g. class has non-copyable members, or inherits from a non-copyable class). Thank you Yksisarvinen for the comment
This means you are not allowed to create a new User from another one.
Then, if you want to store User objects in a vector (as you are "apparently" trying to do in your post, I say "apparently" because the posted code does not compile, I dunno who is this) you cannot store them by value, as the vector contained needs an accessible copy constructor.
See std::vector:
T must meet the requirements of CopyAssignable and CopyConstructible.
However, you can store them as pointers:
std::vector<std::shared_ptr<User>> users;
users.push_back( std::shared_ptr<User>( new User( json ) );

Pushing a DirectX object into a std::queue [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm working on a small release manager that will be used to delete objects once they are old.
I'm using a std::queue to hold the age & pointer to the object.
This is the method that I'm using to push values into the queue:
ID3D12Resource* texture; // declaration
renderPlat->PushToReleaseManager(texture);
std::queue<std::pair<int,void*>> mResourceBin; // declaration
void RenderPlatform::PushToReleaseManager(ID3D12Resource* res)
{
if (!res)
return;
mResourceBin.push(std::pair<int, void*>(0, res));
}
But this is causing an Exception thrown: read access violation / std::_Deque_alloc<std::_Deque_base_types<std::pair<int,void * __ptr64>,std::allocator<std::pair<int,void * __ptr64> > > >::_Myoff(...) returned 0x6B0 :
void push_back(value_type&& _Val)
{ // insert element at end
this->_Orphan_all();
_PUSH_BACK_BEGIN; // <--- The exception is thrown here!!!
this->_Getal().construct(
_Unfancy(this->_Map()[_Block] + _Newoff % _DEQUESIZ),
_STD forward<value_type>(_Val));
_PUSH_BACK_END;
}
The object that I'm trying to delete, is an ID3D12Resource it inherits from IUnknown
Edit:
I'm using: Visual Studio 2015 (v140).
Edit 2:
The ID3D12Resource* object passed to the PushToReleaseManager() is created using ID3D12Device::CreateCommittedResource
I found the problem.
I was getting the RenderPlatform which has the PushToReleaseManager() method like this:
auto rPlat = (dx11on12::RenderPlatform*)(renderPlatform);
This cast was failing because renderPlatform was invalid and it was returning a null pointer. The thing is that I was allowing me to call the method no problem, I guess because it had some junk memory around.
Thanks for the answers!
Try to use smart pointers. They are much better then explicitly try to release memory.

Creating a vector in a method and setting it to a variable

OK so I an new to C++ and am fairly sure this should be a simple question if I can ask it right. Basically this is what I need to work:
printInfoFromVector(this->mycontroller.createVector)
This is the actual code I have:
vector<GasStation>& highPrices = this->myController.findHighestPrice();
this->findPrice(highPrices);
vector<GasStation>& findHighestPrice(){
The problem that I am having is that I can not get they types of highPrices and findHighestPrice() to match. Im fairly sure the problem is because I am passing by ref but I pretty sure that the right way to do it.
Can anyone tell me the correct way to write the assignment statement and the method head so that the types match?
If findHighestPrice is computing a new vector, then you should not return a reference, but an actual vector. Thus you would have:
vector<GasStation> findHighestPrice() { ... }
vector<GasStation> highPrices = this->myController.findHighestPrice();
For example, if you defined findHighestPrice as
vector<GasStation>& findHighestPrice() {
vector<GasStation> stations;
// ...
return stations;
}
then stations will be deallocated when the function returns and highPrices will be undefined.

Recursion restarting loop (C++)

I have a question regarding C++. So I have made this program, that computes all possible combinations to solve a problem using recursion(instead of 9 loops). This is a part of the code:
int used[9];
nMin=1000;
void Combinations(int index)
{
if(index>8)
{
return;
}
for(int i=k;i<4;i++)
{
used[index]=i;
if (sum<nMin && Check())//Checks the solution
{
nMin = sum;
used[i]=0;
return;
}
else
{
Combinations(index+1);
}
}
}
The for loop, that should repeat 4 times resets every time recursive call returns. In other words the loop variable is set to 0. Is that just how it works, and do I have to store current loop variable value, or is there another way.
Edit: thank you guys, for detailed information and your answers. The code worked after a few tweaks.
If I am reading this correctly, your question is whether the loop variable i will be protected/preserved by the recursive calls to Combinations.
The answer is yes, the value of the loop counter will be preserved. The reason is scope. Each time the function is called, the stack creates space for a new variable i scoped to the current call. This means all interactions with i during a function call are with the i created for that specific call.
Note: The C/C++ language standards have no explicit notion of a stack. This is actually an implementation detail for the implementation of automatic storage.
int i is a local variable that exists within the context of that for loop for that instance of that function call. When you make a recursive call to the same function, you're pushing a brand new instance of that function call on the stack, which has its own for loop with its own int i variable. They are in no way connected to each other.
If you want all recursive calls to the function to share a counter, you will need to define it as a static variable, and define it outside of the scope of the for loop, like this:
void Combinations(int index)
{
static int persistentCounter;
This will maintain it's value in recursive calls.