I'm trying to do the following:
ask the user for a name, then ask the user for values (which will be used to construct a collection of vectors), then print out various combinations of the values, then do it all over again.
My problem is that after the first loop and after asking for the name again I get a "segmentation fault (core dump)" error message. I'm assuming this has to do with the vectors which were constructed/defined in the first loop. So, I'm wondering if there is any way to clear these objects after each loop. That is, what I'd like is:
Do {
ask user for name
ask user for values
create vectors from these values
print off certain elements of the vectors
reset/delete name, values, vectors so that I can run the loop again as if it's the first time
} while(condition);
If you can point me towards any useful references that would be great. Thanks in advance.
You can create the vectors outside of the loop, and clear them from within the loop. It could look something like the following:
vector<string> info;
do {
// get input and do whatever
info.clear();
} while (condition);
Some documentation http://www.cplusplus.com/reference/vector/vector/clear/
Update:
My original answer was specifically informing you how to clear the vector, but it seems like there is likely a better solution for you. Given your description there does not seem to be a need to move the declaration outside the loop and clear the vector at the end. Without additional code we have no way of knowing what caused the seg fault and how you should handle this issue properly.
auto iterator = unorderedMap.find(element);
if (iterator == unorderedMap.end()) { //If the element doesn't already exist in the table, create a new entry
iterator = unorderedMap.insert(make_pair((element), vector<unsigned>()).first;
}
iterator->second.push_back(unsigned_number_associated_with_element);
The hashtable is a table of strings and vector<unsigned> (the key is of type string).
element is of type of string.
The code is supposed to do the following:
1) Check if the key element exists in the hash table
2) If it doesn't, create a new entry. If it does, just do the next step.
3) Push element into the entry's vector.
The code compiles fine, but running it gives me an error:
error: attempt to subscript container
with out-of-bounds index 22464, but container only holds 22464 elements
Anyone know why? Commenting out the last line makes the error go away.
I honestly don't know where that error was coming from (although I suspect that it was some sort of unfortunate parenthesization error), but there is no difference between the intent of that code and the following rather simpler code:
unorderedMap[element].push_back(unsigned_number_associated_with_element);
except that the above is probably faster (it will only do one lookup rather than two if the element isn't present) and is certainly easier to read and debug.
How can I use mod(%) operator to get access to a certain element in a vector in c++? The following line is already recognized erroneous by the compiler.
std::rotate((MyVector.begin()+i)%32,MyVector.begin()+j,MyVector.end());
In the MSDN documentation for CComSafeArray::MultiDimSetAt, alIndex is documented as follows:
Pointer to a vector of indexes for each dimension in the array. The rightmost (least significant) dimension is alIndex[0].
In the documentation for CComSafeArray::MultiDimGetAt, alIndex is documented differently:
Pointer to a vector of indexes for each dimension in the array. The leftmost (most significant) dimension is alIndex[0].
This made me think that, to get to the same element, one would need to reverse the order of the indices in a multidimensional array. However, I have not found this to be the case in practice.
Am I misusing this interface and getting lucky, misunderstanding the documentation, or is this possibly an error in the docs?
It seems to be docs error - I'd suggest you to refer to SafeArrayGetElement/SafeArrayPutElement documentation as it seems to be more accurate.
To set and get the same element you should use the same array of indices (without reversing).
By the way, nice catch!
What exactly is an "assert", or more specifically, how do I get rid of an error. When I create a vector of pointers to a class with data member int x, and then do this:
for(I=antiviral_data.begin();I<antiviral_data.end();I++)
{
if((*I)->x>maxx)
{
antiviral_data.erase(I);
}
}
And run the program, I get no errors until x is greater than maxx and I use .erase(), at which point I get this error:
Debug Assertion Failed!
Program: ...My Documents\O.exe File:
...include\vector Line: 116
Expression:
("this->_Has_container()",0)
For information on how your program
can cause an assertion failure, see
the Visual C++ documentation on
asserts.
(Press Retry to debug the application)
[Abort][Retry][Ignore]
Also, if I try to use cout:
cout<<(*antiviral_data.begin())->x<<endl;
I get this error:
Debug Assertion Failed!
Program: ...My Documents\O.exe File:
...include\vector Line: 98
Expression: vector iterator not
deferencable
For information on how your program
can cause an assertion failure, see
the Visual C++ documentation on
asserts.
(Press Retry to debug the application)
[Abort][Retry][Ignore]
Could somebody please tell me why I can't USE any of the data in the vector, and how to fix it?
ALSO: antiviral_data is a vector of pointers, with a single element:
antiviral_data.push_back(new aX1(player.x,player.y,'>'));
If that helps.
The most probable reason why you get the assertion is that you increment I after an erase. Try this instead:
for(I=antiviral_data.begin();I!=antiviral_data.end();)
{
if((*I)->x>maxx) I=antiviral_data.erase(I); else ++I;
}
See also http://www.cppreference.com/wiki/stl/vector/erase , search for invalid iterators on that page.
An assert is typically an expression entered by a developer for debug and error control purposes - you put different "sanity checks" in your code, and have it crash the program if the check is not reached.
For example, imagine you had code that was going to divide two numbers somewhere down the road. Even though you always expect a division by non-zero, you put at assert before the division in case an argument got miscalculated. If the assert fails, it means somewhere up the road there was a failure.
Assertions typically appear only in the debug version in the code (If you use visual C++ you can compile for debug and release). While compiling in release mode would eliminate the results, it is a very bad idea, since you would still have an error and probably really bad results.
Somewhere in the implementation of Vector (is it standard), and speciifcally in line 98, there is an assert. If you have access to the vector code, look to see what the assert is or debug up to that point. This could indicate an error in the vector implementation, or in the code that calls vector.
The stuff you posted gives us some hints of what's going on, but it would be useful if you could paste more of the program, including where the vectors are defined.
The problem is with erase call. You are iterating through a container and at the same time erasing elements from it. After doing an erase, your iterator becomes invalid. If you want to remove elements of a particular value from a vector use erase with remove_if algorithm. This is known as a erase-remove idiom and explained very well in Scott Meyer's Effective STL book. You can also refer to this question Erasing elements from a vector for more information.
You already have a couple of good answers about what is an assertion and why it is being triggered in your code. Now, you may want to consider using STL algorithms for a two pass erasure.
namespace {
struct exceeds : public std::unary_function< TheUnknownType*, bool >
{
exceeds_max( int max ) : maxx( max ) {}
bool operator()( TheUnknownType* data ) {
return data->x < max;
}
private:
int maxx;
};
}
void your_function()
{
std::vector< TheUnknownType* >::iterator new_end;
new_end = std::remove_if( antiviral_data.begin(), antiviral_data.end(), exceeds(maxx) );
antiviral_data.remove( new_end, antiviral_data.end() );
}
The main advantage is that erasing elements in a vector is an expensive operation. For each element erased, all elements from that position to the end of the vector must be moved one position towards the beginning. The second element you erase will force a second move of all the elements from there on... The STL remove_if algorithm performs the moves only once to their final position returning an iterator one past the last element not removed element. Then you can perform one single std::vector<>::remove that will not need to relocate elements.