Map inserstion failure: can not overwrite first element? - c++

static std::map <unsigned int, CPCSteps> bestKvariables;
inline void copyKBestVar(MaxMinVarMap& vMaxMinAll, size_t& K, std::vector<unsigned int>& temp)
{
// copy top k variables and store in a vector.
MaxMinVarMap::reverse_iterator iter1;
size_t count;
for (iter1 = vMaxMinAll.rbegin(), count = 0; iter1 != vMaxMinAll.rend()&& count <= K; ++iter1, ++count)
{
temp.push_back(iter1->second);
}
}
void myAlgo::phase1(unsigned int& vTarget)
{
CPCSteps KBestForT; // To store kbest variables for only target variable finally put in a global storage
KBestForT.reserve(numVars);
std::vector<unsigned int> tempKbest;
tempKbest.reserve(numVars);
.......
.......
copyKBestVar(mapMinAssoc, KBestSize, tempKbest); // Store k top variables as a k best for this CPC variable for each step
KBestForT.push_back(tempKbest);
.....
.....
bestKvariables.insert(make_pair(vTarget, KBestForT)); // Store k best in a Map
.....
....
}
The Problem: Map "bestKvariables" is not overwriting the first element, but it keeps updating the rest of the elements. I tried to debug it but the problem i found is in insert command.
Thanks in advance for helping.
Another Question: whether i can reserve the size of a map(like vector.reserve(..)) in the beginning to avoid the insertion cost.
Sorry for providing insufficient information.
I means if there are four vTarget variables 1, 2, 3, 4. I do some statistical calculations for each variable.
There are more than one iterations for these variables, i would like to store top k results of each variable in a map to use it next iteration.
I saw the first inserted variable(with key unsigned int "vTarget") is not updated on further iterations(it remains the value inserted on first iteration).
But the other variables (keys inserted after the first) are remains updated.

Another Question: whether i can reserve the size of a map(like vector.reserve(..)) in the beginning to avoid the insertion cost.
std::map does not have a reserve() function unlike std::vector.
Usually, the Standard library provides functions for containers that provide and ensure good performance or provide a means to achieve the same.
For a container like std::vector reallocation of its storage can be a very costly
operation. A simple call to push_back() can lead to every element in the std::vector to be copied to a newly allocated block of memory. A call to reserve() can avoid these unnecessary allocations and copy operations for std::vector and hence the same is provided for it.
std::map never needs to copy all of the existing/remaining elements simply because a new element was inserted or removed. Hence it does not provide any such function.
Though the Standard does not specify how a std::map should be implemented the behavior expected and the complexity desired ensures that most implementations implement it as a tree, unlike std::vector which needs elements to be allocated in contiguous memory locations.

map::insert isn't supposed to update/overwrite anything, just insert not-yet-present elements. Use operator[] for updating, it also inserts elements when the specified key is not present yet.

Related

Which container should I use for random access, cheap addition and removal (without de/allocation), with a known maximum size?

I need the lighter container that must store till 128 unsigned int.
It must add, edit and remove each element accessing it quickly, without allocating new memory every time (I already know it will be max 128).
Such as:
add int 40 at index 4 (1/128 item used)
add int 36 at index 90 (2/128 item used)
edit to value 42 the element at index 4
add int 36 at index 54 (3/128 item used)
remove element with index 90 (2/128 item used)
remove element with index 4 (1/128 item used)
... and so on. So every time I can iterate trought only the real number of elements added to the container, not all and check if NULL or not.
During this process, as I said, it must not allocating/reallocating new memory, since I'm using an app that manage "audio" data and this means a glitch every time I touch the memory.
Which container would be the right candidate?
It sounds like a "indexes" queue.
As I understand the question, you have two operations
Insert/replace element value at cell index
Delete element at cell index
and one predicate
Is cell index currently occupied?
This is an array and a bitmap. When you insert/replace, you stick the value in the array cell and set the bitmap bit. When you delete, you clear the bitmap bit. When you ask, you query the bitmap bit.
You can just use std::vector<int> and do vector.reserve(128); to keep the vector from allocating memory. This doesn't allow you to keep track of particular indices though.
If you need to keep track of an 'index' you could use std::vector<std::pair<int, int>>. This doesn't allow random access though.
If you only need cheap setting and erasing values, just use an array. You
can keep track of what cells are used by marking them in another array (or bitmap). Or by just defining one value (e.g. 0 or -1) as an "unused" value.
Of course, if you need to iterate over all used cells, you need to scan the whole array. But that's a tradeoff you need to make: either do more work during adding and erasing, or do more work during a search. (Note that an .insert() in the middle of a vector<> will move data around.)
In any case, 128 elements is so few, that a scan through the whole array will be negligible work. And frankly, I think anything more complex than a vector will be total overkill. :)
Roughly:
unsigned data[128] = {0}; // initialize
unsigned used[128] = {0};
data[index] = newvalue; used[index] = 1; // set value
data[index] = used[index] = 0; // unset value
// check if a cell is used and do something
if (used[index]) { do something } else { do something else }
I'd suggest a tandem of vectors, one to hold the active indices, the other to hold the data:
class Container
{
std::vector<size_t> indices;
std::vector<int> data;
size_t index_worldToData(size_t worldIndex) const
{
auto it = std::lower_bound(begin(indices), end(indices), worldIndex);
return it - begin(indices);
}
public:
Container()
{
indices.reserve(128);
data.reserve(128);
}
int& operator[] (size_t worldIndex)
{
return data[index_worldToData(worldIndex)];
}
void addElement(size_t worldIndex, int element)
{
auto dataIndex = index_worldToData(worldIndex);
indices.insert(it, worldIndex);
data.insert(begin(data) + dataIndex, element);
}
void removeElement(size_t worldIndex)
{
auto dataIndex = index_worldToData(worldIndex);
indices.erase(begin(indices) + dataIndex);
data.erase(begin(indices) + dataIndex);
}
class iterator
{
Container *cnt;
size_t dataIndex;
public:
int& operator* () const { return cnt.data[dataIndex]; }
iterator& operator++ () { ++dataIndex; }
};
iterator begin() { return iterator{ this, 0 }; }
iterator end() { return iterator{ this, indices.size() }; }
};
(Disclaimer: code not touched by compiler, preconditions checks omitted)
This one has logarithmic time element access, linear time insertion and removal, and allows iterating over non-empty elements.
You could use a doubly-linked list and an array of node pointers.
Preallocate 128 list nodes and keep them on freelist.
Create a empty itemlist.
Allocate an array of 128 node pointers called items
To insert at i: Pop the head node from freelist, add it to
itemlist, set items[i] to point at it.
To access/change a value, use items[i]->value
To delete at i, remove the node pointed to by items[i], reinsert it in 'freelist'
To iterate, just walk itemlist
Everything is O(1) except iteration, which is O(Nactive_items). Only caveat is that iteration is not in index order.
Freelist can be singly-linked, or even an array of nodes, as all you need is pop and push.
class Container {
private:
set<size_t> indices;
unsigned int buffer[128];
public:
void set_elem(const size_t index, const unsigned int element) {
buffer[index] = element;
indices.insert(index);
}
// and so on -- iterate over the indices if necessary
};
There are multiple approaches that you can use, I will cite them in order of effort expended.
The most affordable solution is to use the Boost non-standard containers, of particular interest is flat_map. Essentially, a flat_map offers the interface of a map over the storage provided by a dynamic array.
You can call its reserve member at the start to avoid memory allocation afterward.
A slightly more involved solution is to code your own memory allocator.
The interface of an allocator is relatively easy to deal with, so that coding an allocator is quite simple. Create a pool-allocator which will never release any element, warm it up (allocate 128 elements) and you are ready to go: it can be plugged in any collection to make it memory-allocation-free.
Of particular interest, here, is of course std::map.
Finally, there is the do-it-yourself road. Much more involved, quite obviously: the number of operations supported by standard containers is just... huge.
Still, if you have the time or can live with only a subset of those operations, then this road has one undeniable advantage: you can tailor the container specifically to your needs.
Of particular interest here is the idea of having a std::vector<boost::optional<int>> of 128 elements... except that since this representation is quite space inefficient, we use the Data-Oriented Design to instead make it two vectors: std::vector<int> and std::vector<bool>, which is much more compact, or even...
struct Container {
size_t const Size = 128;
int array[Size];
std::bitset<Size> marker;
}
which is both compact and allocation-free.
Now, iterating requires iterating the bitset for present elements, which might seem wasteful at first, but said bitset is only 16 bytes long so it's a breeze! (because at such scale memory locality trumps big-O complexity)
Why not use std::map<int, int>, it provides random access and is sparse.
If a vector (pre-reserved) is not handy enough, look into Boost.Container for various “flat” varieties of indexed collections. This will store everything in a vector and not need memory manipulation, but adds a layer on top to make it a set or map, indexable by which elements are present and able to tell which are not.

Filling a vector with out-of-order data in C++

I'd like to fill a vector with a (known at runtime) quantity of data, but the elements arrive in (index, value) pairs rather than in the original order. These indices are guaranteed to be unique (each index from 0 to n-1 appears exactly once) so I'd like to store them as follows:
vector<Foo> myVector;
myVector.reserve(n); //total size of data is known
myVector[i_0] = v_0; //data v_0 goes at index i_0 (not necessarily 0)
...
myVector[i_n_minus_1] = v_n_minus_1;
This seems to work fine for the most part; at the end of the code, all n elements are in their proper places in the vector. However, some of the vector functions don't quite work as intended:
...
cout << myVector.size(); //prints 0, not n!
It's important to me that functions like size() still work--I may want to check for example, if all the elements were actually inserted successfully by checking if size() == n. Am I initializing the vector wrong, and if so, how should I approach this otherwise?
myVector.reserve(n) just tells the vector to allocate enough storage for n elements, so that when you push_back new elements into the vector, the vector won't have to continually reallocate more storage -- it may have to do this more than once, because it doesn't know in advance how many elements you will insert. In other words you're helping out the vector implementation by telling it something it wouldn't otherwise know, and allowing it to be more efficient.
But reserve doesn't actually make the vector be n long. The vector is empty, and in fact statements like myVector[0] = something are illegal, because the vector is of size 0: on my implementation I get an assertion failure, "vector subscript out of range". This is on Visual C++ 2012, but I think that gcc is similar.
To create a vector of the required length simply do
vector<Foo> myVector(n);
and forget about the reserve.
(As noted in the comment you an also call resize to set the vector size, but in your case it's simpler to pass the size as the constructor parameter.)
You need to call myVector.resize(n) to set (change) the size of the vector. calling reserve doesn't actually resize the vector, it just makes it so you can later resize without reallocating memory. Writing past the end of the vector (as you are doing here -- the vector size is still 0 when you write to it) is undefined behavior.

c++ vector insertion and reading

I am inserting elements with push_back in a vector. I want to read the data in FIFO and using iterator assigned to begin of vector. Is there any other approach of reading data in FIFO in a vector?
You may use a std::deque() and its pop_front() method.
You can access the elements of a vecotr just like you would access the elements of an array:
std::vector<std::string> vec;
// Excluded: push items onto vec
for (int i = 0; i < vec.size(); ++i) {
// Example:
std::cout << vec[i];
}
The code would be:
auto value = myvector[0];
myvector.erase(myvector.begin());
However, removing elements from the beginning (or somewhere in between) is slow, because it must copy the whole array. Access is fast though: vector allows random access (i.e. access by any explicit index) in O(1) (i.e. constant access time, i.e. very fast).
But another container structure instead of vector might make more sense for you, e.g. list or deque. Some STL implementations (or other framework) also have something like rope which is in many cases the best of both worlds.
There's nothing special to pay attention to. To insert, use
push_back, to extract, you need something like:
if ( !fifo.empty() ) {
ValueType results = fifo.front();
fifo.erase( fifo.begin() );
}
(Don't forget to check for empty before trying to remove an
element.)
An important point to remember is that both push_back and
in some cases erase can invalidate iterators, so you don't
want to keep iterators into the underlying vector hanging
around.

inserting into the middle of an array

I have an array int *playerNum which stores the list of all the numbers of the players in the team. Each slot e.g playerNum[1]; represents a position on the team, if I wanted to add a new player for a new position on the team. That is, inserting a new element into the array somewhere near the middle, how would I go about doing this?
At the moment, I was thinking you memcpy up to the position you want to insert the player into a new array and then insert the new player and copy over the rest of it?
(I have to use an array)
If you're using C++, I would suggest not using memcpy or memmove but instead using the copy or copy_backward algorithms. These will work on any data type, not just plain old integers, and most implementations are optimized enough that they will compile down to memmove anyway. More importantly, they will work even if you change the underlying type of the elements in the array to something that needs a custom copy constructor or assignment operator.
If you have to use an array, after having made sure you have enough storage (using realloc if necessary), use memmove to shift the items from the insertion point to the end by one position, then save your new player at the desired location.
You can't use memcpy if the source and target areas overlap.
This will fail as soon as the objects in your array have non-trivial copy-constructors, and it's not idiomatic C++. Using one of the container classes is much safer (std::vector or std::list for instance).
Your solution using memcpy is correct (under few assumptions mentionned by other).
However, and since you are programming in C++. It is probably a better choice to use std::vector and its insert method.
vector<int> myvector (3,100);
myvector.insert ( 10 , 42 );
An array takes a contiguous block of memory, there is no function for you to insert an element in the middle. you can create a new one of size larger than the origin's by one then copy the original array into the new one plus the new member
for(int i=0;i<arSize/2;i++)
{
newarray[i]<-ar[i];
}
newarray[i+1]<-newelemant;
for(int j=i+1<newSize;j++,i++)
{
newarray[i]<-ar[i];
}
if you use STL, ting becomes easier, use list.
As you're talking about an array and "insert" I assume that it is a sorted array. You don't necessarily need a second array provided that the capacity N of your existing array is large enough to store more entries (N>n, where n is the number of current entries). You can move the entries from k to n-1 (zero-indexed) to k+1 to n, where k is the desired insert position. Insert the new element at index position k and increase n by one. If the array is not large enough in the beginning, you can follow your proposed approach or just reallocate a new array of larger capacity N' and copy the existing data before applying the actual insert operation described above.
BTW: As you're using C++, you could easily use std::vector.
While it is possible to use arrays for this, C++ has a better solutions to offer. For starters, try std::vector, which is a decent enough general-purpose container, based on a dynamically-allocated array. It behaves exactly like an array in many cases.
Looking at your problem, however, there are two downsides to arrays or vectors:
Indices have to be 0-based and contiguous; you cannot remove elements from the middle without losing key/value associations for everything after the removed element; so if you remove the player on position 4, then the player from position 9 will move to position 8
Random insertion and deletion (that is, anywhere except the end) is expensive - O(n), that is, execution time grows linearly with array size. This is because every time you insert or delete, a part of the array needs to be moved.
If the key/value thing isn't important to you, and insertion/deletion isn't time critical, and your container is never going to be really large, then by all means, use a vector. If you need random insertion/deletion performance, but the key/value thing isn't important, look at std::list (although you won't get random access then, that is, the [] operator isn't defined, as implementing it would be very inefficient for linked lists; linked lists are also very memory hungry, with an overhead of two pointers per element). If you want to maintain key/value associations, std::map is your friend.
Losting the tail:
#include <stdio.h>
#define s 10
int L[s];
void insert(int v, int p, int *a)
{
memmove(a+p+1,a+p,(s-p+1)*4);
*(a+p) = v;
}
int main()
{
for(int i=0;i<s;i++) L[i] = i;
insert(11,6, L);
for(int i=0;i<s;i++) printf("%d %d\n", L[i], &L[i]);
return 0;
}

Stumped at a simple segmentation fault. C++

Could somebody be kind to explain why in the world this gives me a segmentation fault error?
#include <vector>
#include <iostream>
using namespace std;
vector <double>freqnote;
int main(){
freqnote[0] = 16.35;
cout << freqnote[0];
return 0;
}
I had other vectors in the code and this is the only vector that seems to be giving me trouble.
I changed it to vector<int>freqnote; and changed the value to 16 and I STILL get the segmentation fault. What is going on?
I have other vector ints and they give me correct results.
Replace
freqnote[0] = 16.35;
with
freqnote.push_back(16.35);
and you'll be fine.
The error is due to that index being out-of-range. At the time of your accessing the first element via [0], the vector likely has a capacity of 0. push_back(), on the other hand, will expand the vector's capacity (if necessary).
You can't initialise an element in a vector like that.
You have to go:
freqnote.push_back(16.35),
then access it as you would an array
You're accessing vector out of bounds. First you need to initialize vector specifying it's size.
int main() {
vector<int> v(10);
v[0] = 10;
}
As has been said, it's an issue about inserting an out of range index in the vector.
A vector is a dynamically sized array, it begins with a size of 0 and you can then extend/shrink it at your heart content.
There are 2 ways of accessing a vector element by index:
vector::operator[](size_t) (Experts only)
vector::at(size_t)
(I dispensed with the const overloads)
Both have the same semantics, however the second is "secured" in the sense that it will perform bounds checking and throw a std::out_of_range exception in case you're off bound.
I would warmly recommend performing ALL accesses using at.
The performance penalty can be shrugged off for most use cases. The operator[] should only be used by experts, after they have profiled the code and this spot proved to be a bottleneck.
Now, for inserting new elements in the vector you have several alternatives:
push_back will append an element
insert will insert the element in front of the element pointed to by the iterator
Depending on the semantics you wish for, both are to be considered. And of course, both will make the vector grow appropriately.
Finally, you can also define the size explicitly:
vector(size_t n, T const& t = T()) is an overload of the constructor which lets you specify the size
resize(size_t n, T const& t = T()) allows you to resize the vector, appending new elements if it gets bigger than it was
Both method allow you to supply an element to be copied (exemplar) and default to copying a default constructed object (0 if T is an int) if you don't supply the exemplar explicitly.
Besides using push_back() to store new elements, you can also call resize() once before you start using the vector to specify the number of elements it contains. This is very similar to allocating an array.