STL map find doesn't work properly [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 6 years ago.
Improve this question
I'm having a map containing 1323 records, which is getting filled the following way:
std::map<uint32_t, House*> m_houses;
[...]
void OnReceiveHousePacket(HouseTable_t* recvTable, int32_t size) {
m_houses.clear();
for (int32_t i = 0; i < size; ++i, ++recvTable) {
House* h = new House;
memcpy(&h->table, recvTable, sizeof (HouseTable_t));
m_houses.insert(std::make_pair(recvTable->clientId, h));
}
}
The issue I'm having with this, is that when I am trying to find a record by key:
const House* Get(uint32_t clientId) {
auto it = m_houses.find(clientId);
if (it == m_houses.end()) {
return nullptr;
}
return it->second;
}
It returns nullptr, although the key exists and I am sure about that.
m_houses.count(clientId) returns 0 as well
However, when I change the Get([...]) function contents to the following loop, everything works like a charm without any issues which proves that the record really exists in the map:
for (const auto& h : m_houses) {
if (h.first == clientId) {
return h.second;
}
}
return nullptr;
It's the first time I am having an issue like that with STL's map.
What is the problem? I've always been using this way to find a record and never faced such issue.
edit
HouseTable_t and House:
struct HouseTable_t {
char name[24 + 1];
char owner[64 + 1];
int clientId;
int type;
int rank;
unsigned char identifier;
}
class House{
public:
House() = default;
HouseTable_t m_table;
int id;
int data;
};

This:
memcpy(&h, ...
Should be:
memcpy(h, ...
Otherwise you're trashing the pointer.

Related

Why is my binary search algorithm so slow despite theoretically being O(log n) time? [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 2 months ago.
Improve this question
I implemented a binary search, and in theory should run in O(log N) time, and this holds up when counting the number of times it is looped through. However, when it is run, it seems to be extremely slow.
int binary_search(int i, vector<int> list) {
int min_ = 0;
int max_ = list.size();
while (max_ != min_+1) {
if (list[(max_+min_)/2] > i) {
max_ = (max_+min_)/2;
} else if (list[(max_+min_)/2] <= i) {
min_ = (max_+min_)/2;
}
}
return min_;
}
Can anyone explain why my algorithm is so slow?
For starters, you're making a copy of the vector<int> list that is passed in. Change it to be pass by reference:
Instead of this:
int binary_search(int i, vector<int> list) {
This:
int binary_search(int i, const vector<int>& list) {

What's the difference b/w map[key] vs map.count(key) ? (particularly in this code) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
So I was Solving a leetcode Problem and one dumb mistake made in debugg for more than an hour.
Leetcode Question
Answers(both working and not working)
Working code:
`
class Solution {
public:
int longestPalindrome(vector<string>& words) {
unordered_map<string,int> map;
for(string s:words){
map[s]++;
}
bool isOdd = false;
int ans = 0;
for(auto i:map){
string rv = i.first;
reverse(rv.begin(),rv.end());
if(i.first[0]==i.first[1]){
if(i.second%2==0)
ans+=i.second;
else{
ans+= i.second-1;
isOdd = true;
}
}
else if(i.first[0]<i.first[1] && map.count(rv)){
ans += 2*min(i.second,map[rv]);
}
}
if(isOdd){
ans++;
}
return 2*ans;
}
};
Not working code:
`
class Solution {
public:
int longestPalindrome(vector<string>& words) {
unordered_map<string,int> map;
for(string s:words){
map[s]++;
}
bool isOdd = false;
int ans = 0;
for(auto i:map){
string rv = i.first;
reverse(rv.begin(),rv.end());
if(i.first[0]==i.first[1]){
if(i.second%2==0)
ans+=i.second;
else{
ans+= i.second-1;
isOdd = true;
}
}
else if(i.first[0]<i.first[1] && map[rv]){
ans += 2*min(i.second,map[rv]);
}
}
if(isOdd){
ans++;
}
return 2*ans;
}
};
The only difference between both code is map[rv] ==> map.count(rv)
test case which is giving error:
["oo","vv","uu","gg","pp","ff","ss","yy","vv","cc","rr","ig","jj","uu","ig","gb","zz","xx","ff","bb","ii","dd","ii",
"ee","mm","qq","ig","ww","ss","tt","vv","oo","ww","ss","bi","ff","gg","bi","jj","ee","gb",
"qq","bg","nn","vv","oo","bb","pp","ww","qq","mm","ee","tt","hh","ss","tt","ee","gi","ig","uu","ff","zz",
"ii","ff","ss","gi","yy","gb","mm","pp","uu","kk","jj","ee"]
Can anyone please help me?
I've tried googling this stuff but couldn't find it. then i've tried asking few people on discord. but no progress.
I just wanna know why above(not working part) code in not working.
What is the deal with map[key] and map.count(key)?
When should i use which one?
std::map.count() will check, if an element with a given key exists. It will not modify the container. Please see here. It is even defined as constto indicate that fact.
The std::maps index operator is different. It
returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist.
So, if the key does not exist, it will add an entry to the map, with this new key.
Therefore your second code cannot work.
map[rv] isn't a regular getter. It inserts default element if key is not found.
so you mutate (unordered_map) map whereas you iterate on it (which (might) invalidate iterator, making you loop undefined behavior).

How to Create an Array with Same Element repeated multiple times in Arduino? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
**array=[symbol,count,symbol,count.....]
for eg: array=[3,2,5,4..]
new_array=[3,3,5,5,5,5...]**
int array[]={25,6,10,2,4,3,9,5};
int value1[16]={0};
Serial.print("\n RLE decoded");
for(i=0;i<len;i++)
{
if(i%2==0)
{
value[i] = array[i];
i=i+1;
count=array[i];
}
for(j=0; j<count;j++)
{
Serial.print(value[i]);
Serial.print('\t');
}
How to Create an Array with Same Element repeated multiple times in Arduino?
This code is working properly and we are able to print repeatedly the symbols but the problem with this code is :: the repeated the values are not getting stored to a new array. we tried with declaring a new array to store the repeated values but it is not working!!
An array is a collection of the same elements, but symbol and count are obviously different things. To group different things together, struct was invented in the earliest days of C
struct {char symbol; byte count;} input[] = {
{'a', 2}, {'X' ,3} ,{'!', 1}
};
const byte inputcount = sizeof(input)/sizeof(input[0]); // 3 in this test
char expanded[20]; // will get the result
void setup() {
Serial.begin(9600);
char* resultpos = expanded;
for (auto& elem:input) {
for (byte p = 0; p < elem.count; p++) {
*resultpos++ = elem.symbol;
}
}
*resultpos = 0; // to make it a printable char array
Serial.println(expanded); // should give "aaXXX!"
}
void loop() {}
If you prefer, you can use the classic type of for loop as well. But this for each is really nice, IMO.

incompatible types in assignment null [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 7 years ago.
Improve this question
I Keep getting this error when I try to set the first char in firstname and lastname to a null and return it to a 1.
my code is...
int DeregisterStudent(int SID, struct studentdata SRecord[])
{
int index;
index = SRecordSearch(SID, MAXRECS, SRecord);
if(index >= 0)
{
SRecord[index].sid = 0;
SRecord[index].lastname = '\0';
SRecord[index].firstname = '\0';
return 1;
}
return 0;
}
and the error I get is error:incompatible type in assignment
for these two lines
SRecord[index].lastname = '\0';
SRecord[index].firstname = '\0';
You are not writing to the string correctly, it should be
SRecord[index].lastname[0] = '\0';
or
SRecord[index].lastname = "";
depending on how the struct was declared. In the second case you might be overwriting a dynamically allocated string pointer, in which case it should be free()ed.

Segmentation fault on list in C++ [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 8 years ago.
Improve this question
I'm using a class which holds a private list:
class Set
{
private:
list<long long unsigned> ways; //holds tags of addresses
and as part of the class's functionality I'm managing a LIFO on the list 'ways':
list<long long unsigned>::iterator it = ways.begin();
while (it!= ways.end()) //looks for the tag in the list
{
if ((*it) == tag) //tag is found in this set. moves the tag to the end of the list
{
ways.erase(it);
ways.push_back(tag);
return true;
}
it++;
}
return false;
and:
if (occupied < maxWays) //if the set is not all used up just pushes tag in the end
{
ways.push_back(tag);
occupied++;
return false;
}
else // if used up pops the front member (the least recently used one)
{
ways.pop_front();
ways.push_back(tag);
}
return true;
Nothing else touches 'ways' and nothing else erases the class 'set'.
Multiple instances of the class 'set' are created at the beginning.
During operation I'm getting Segmentation Fault for
list<long long unsigned>::iterator it = ways.begin();
which occurs after a long run. Trying to print the address of 'ways' before this line shows that at the point that I'm about to get Segmentation Fault the address of 'ways' changed dramatically.
All the previous times it was around 0x6000xxxxx for each instance, and at that time it was 0x23.
I don't have a clue what can cause that, please assist.
It might be that you delete an element from the list, and then increment the iterator, which points to the deleted element.
You probably need to forward the iterator first, and then remove the previous, to achieve what you want.
See:
Can you remove elements from a std::list while iterating through it?
EDIT: See also the return value of erase(), and similar operations that modify the iterator bag.
http://www.cplusplus.com/reference/list/list/erase/
Are you initiliazing 'occupied' and 'maxWays' ? If not, see example where it fails as we are calling ways.pop_front() on empty list ways
class Set
{
public:
Set(int max)
{
maxWays = max;
occupied = 10; // Say randomly stored value 10 is more than maxWays = 5
}
bool search(long long tag)
{
list<long long unsigned>::iterator it = ways.begin();
while (it!= ways.end()) {
if ((*it) == tag) {
ways.erase(it);
ways.push_back(tag);
return true;
}
it++;
}
return false;
}
bool add(long long tag)
{
if (occupied < maxWays) {
ways.push_back(tag);
occupied++;
return false;
}
else {
ways.pop_front(); // may fail here
ways.push_back(tag);
}
return true;
}
private:
list<long long unsigned> ways;
int maxWays;
int occupied;
};
int main()
{
Set set(5);
cout << set.add(100) << endl;
return 0;
}