Program receives `SIGTRAP` when deallocating vector - c++

I have this code which is supposed to look for elements present in all vectors in a std::vector<std::vector<int>>:
for(int x = 0;x < list.size();x++){
for(int y = 0;y < list[x].size();y++){
std::vector<std::vector<int>::iterator> ptr;
for(int z = 1;z < list.size();z++){
std::vector<int>::iterator iter = std::find(list[z].begin(),
list[z].end(), list[x][y]);
if(iter != list[z].end()){
ptr.push_back(iter);
}else
goto fail;
}
list[0].erase(list[0].begin() + y);
for(int z = 1;z <= ptr.size();z++){
list[z].erase(ptr[z - 1]);
}
fail: continue;
}
}
The program always produces wrong output and randomly crashes. Debugging shows that it receives SIGTRAP when deconstructing list in ntdll. This happens randomly, but the program never works correctly. I don't have any breakpoints in the code.

These are the errors I found in the code some time after asking this question:
The code for determining which iterator is from which array was designed only for list[0], instead of being designed for list[x], causing erase() being called with iterators belonging to another vector, causing memory corruption.
x was replaced with 0 in some places (forgot to change it).
list was being corrupted by other code in the program (fixed now).
These are the fixes:
Used an iterator to std::vector<std::vector<int>::iterator> and if(z==x)continue;else{list[z].erase(*iter); iter++;} to make sure iter always points to the correct element.
Replaced 0 with x.
Fixed problems in other places in the program.
The program works correctly now, thanks for trying to help me.

Related

C++ time limit exceeded when it doesn't even execute the function

While I was solving a problem in LeetCode, I found something very strange.
I have this line which I assume gives me a time limit exceeded error:
s.erase(i-k, k);
when I comment(//) this line, it doesn't show me time exceed error, but the strange part was, it has never executed even when i didn't comment it.
below is the entire code.
and Here is the problem link.
class Solution {
public:
string removeDuplicates(string s, int k) {
char prev = s[0];
int cnt = 1;
cnt = 1;
for(int i = 1; i < s.size() + 1; i++){
if(s[i] == prev){
cnt++;
} else {
if(cnt == k){
// when input is "abcd" it never comes to this scope
// which is impossible to run erase function.
s.erase(i-k, k);
i = 0;
}
if(i >= s.size()) break;
cnt = 1;
prev = s[i];
}
}
return s;
}
};
When Input is "abcd", it never even go to the if scope where 'erase' function is in.
Although 'erase' function never run, it still affect on the time complexity, and I can't get the reason.
Does anyone can explain this? or is this just problem of LeetCode?
Many online contest servers report Time Exceeding when program encounters critical error (coding bug) and/or crashes.
For example error of reading out of bounds of array. Or dereferencing bad (junk) pointers.
Why Time Exceeded. Because with critical error program can hang up and/or crash. Meaning it also doesn't deliver result in time.
So I think you have to debug your program to find all coding errors, not spending your time optimizing algorithm.
Regarding this line s.erase(i-k, k); - it may crash/hang-up when i < k, then you have negative value, which is not allowed by .erase() method. When you get for example i - k equal to -1 then size_t type (type of first argument of erase) will overflow (wrap around) to value 18446744073709551615 which is defnitely out of bounds, and out of memory border, hence your program may crash and/or hang. Also erase crashes when there is too many chars deleted, i.e. for erase s.erase(a, b) you have to watch that a + b <= s.size(), it is not controlled by erase function.
See documentation of erase method, and don't put negative values as arguments to this method. Check that your algorithm never has negative value i.e. never i < k when calling s.erase(i-k, k);, also never i-k + k > s.size(). To make sure there is no program crash you may do following:
int start = std::min(std::max(0, i-k), int(s.size()));
int num = std::min(k, std::max(0, int(s.size()) - start));
s.erase(start, num);

Removing first three elements of 2d array C++

So here's my problem.. I have a 2d array of 2 char strings.
9D 5C 6S 9D KS 4S 9D
9S
If 3 found I need to delete the first 3 based on the first char.
card
My problem is I segfault almost anything i do...
pool is the 2d vector
selection = "9S";
while(col != GameBoard::pool.size() ){
while(GameBoard::pool[col][0].at(0) == selection.at(0) || cardsRem!=0){
if(GameBoard::pool[col].size() == 1){
GameBoard::pool.erase(GameBoard::pool.begin() + col);
cardsRem--;
}
else{
GameBoard::pool[col].pop_back();
cardsRem--;
}
}
if(GameBoard::pool[col][0].at(0) != selection.at(0)){
col++;
}
}
I've tried a series of for loops etc, and no luck! Any thoughts would save my sanity!
So I've tried to pull out a code segment to replicate it. But I can't...
If I run my whole program in a loop it will eventually throw a segfault. If I run that exact code in the same circumstance it doesn't... I'm trying to figure out what I'm missing. I'll get back in if I figure out exactly where my issue is..
So in the end the issue is not my code itself, i've got memory leaks or something somewhere that are adding up to eventually crash my program... That tends to be in the same method each time I guess.
The safer and most efficient way to erase some elements from a container is to apply the erase-remove idiom.
For instance, your snippet can be rewritten as the following (which is testable here):
using card_t = std::string;
std::vector<std::vector<card_t>> decks = {
{"9D", "5C", "6S", "9D", "KS", "4S", "9D"},
{"9S"}
};
card_t selection{"9S"};
// Predicate specifing which cards should be removed
auto has_same_rank = [rank = selection.at(0)] (card_t const& card) {
return card.at(0) == rank;
};
auto & deck = decks.at(0);
// 'std::remove_if' removes all the elements satisfying the predicate from the range
// by moving the elements that are not to be removed at the beginning of the range
// and returns a past-the-end iterator for the new end of the range.
// 'std::vector::erase' removes from the vector the elements from the iterator
// returned by 'std::remove_if' up to the end iterator. Note that it invalidates
// iterators and references at or after the point of the erase, including the
// end() iterator (it's the most common cause of errors in code like OP's).
deck.erase(std::remove_if(deck.begin(), deck.end(), has_same_rank),
deck.end());
So for anyone else in the future who comes across this...
The problem is I was deleting an element in the array in a loop, with the conditional stop was it's size. The size is set before hand, and while it was accounted for in the code it still left open the possibility for while(array.size() ) which would be locked in at 8 in the loop be treated as 6 in the code.
The solution was to save the location in the vector to delete and then delete them outside of the loop. I imagine there is a better, more technical answer to this, but it works as intended now!
for (double col = 0; col < size; ++col)
{
if(GameBoard::pool[col][0].at(0) == selection.at(0)){
while(GameBoard::pool[col][0].at(0) == selection.at(0) && cardsRem !=0){
if( GameBoard::pool[col].size() > 1 ){
GameBoard::pool[col].pop_back();
cardsRem--;
}
if(GameBoard::pool[col].size() <2){
toDel.insert ( toDel.begin() , col );
//GameBoard::pool.erase(GameBoard::pool.begin() + col);
cardsRem--;
size--;
}
}
}
}
for(int i = 0; i< toDel.size(); i++){
GameBoard::pool.erase(GameBoard::pool.begin() + toDel[i]);
}

My Visual Studio 2012 program works in Debug, release without debug (ctrl + F5) but not release. How do I fix?

As stated above my program works in Debug and Release without debug (ctrl + F5) however does not work in simply Release.
Just to clarify I have already checked to see if I have some uninitialized variables and I haven't (to the best of my knowledge anyway but I have spent quite some time looking).
I believe to have localized the issue and what I have come across is, in my opinion, very bizarre. First I set up the break points as shown in the picture below:
Then I run the program in release. And instantly the top break point moves:
I found this extremely odd. Now note the number 6302 assigned to 'n'. This number is correct and what I hoped to pass through. Now watch as I continue through the program.
We are still in good shape but then it turns for the worst.
'n' changes to 1178521344, which messes up the rest of my code.
Would someone be able to shed some light on the situation, and even better, offer a solution.
Thanks,
Kevin
Here is the rest of the function if it helps:
NofArr = n;
const int NA = n;
const int NAless = n-1;
double k_0 = (2*PI) / wavelength;
double *E = new double[NAless]; // array to hold the off-diagonal entries
double *D = new double[NA]; // array to hold the diagonal entries on input and eigenvalues on output
int sizeofeach = 0;
trisolver Eigen;
int* start; int* end;
vector< vector<complex <double>> > thebreakup = BreakUp(refidx, posandwidth, start, end);
for(int j = 0; j < (int)thebreakup.size(); j++){
// load the diagonal entries to D
for(int i =0; i < (int)thebreakup[j].size(); i++){
D[i] = -((double)2.0/(dx*dx)) + (k_0*k_0*thebreakup[j][i].real()*thebreakup[j][i].real());
}
// load the off diagonal
for(int i = 0; i < (int)thebreakup[j].size(); i++){
E[i] = (double)1.0 / (dx*dx);
}
sizeofeach = (int)thebreakup[j].size();
double *arr1= new double[sizeofeach];
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
complex <double> tmp( PhaseAndAmp[j][1]*cos(PhaseAndAmp[j][0]), PhaseAndAmp[j][1]*sin(PhaseAndAmp[j][0]));
// rebuild the break up with the mode
for(int i = 0; i < (int)thebreakup[j].size(); i++){
thebreakup[j][i] = (complex<double>(arr1[i],0.0)) * tmp ;
}
delete []arr1;
}
vector<complex<double>> sol = rebuild(thebreakup, start, end);
delete [] E;
delete [] D;
delete [] start;
delete [] end;
return sol;
I'm writing this as an answer, because it's way harder to write as a comment.
What strikes me immediately is the array "arr1"
First you allocate new memory and store a pointer to it in the variable arr1
double *arr1= new double[sizeofeach];
Then, immediately, you overwrite the address.
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
Later, you delete something. Is it safe?
delete []arr1;
It's not the double array you allocated, but something eigensolve returned. Are you sure you have the right to delete it? Try removing the delete here. Also, fix the memory leak too, by removing allocation in the first line I gave.
What worries me even more is that the "this" pointer changes. There is some nasty problem somewhere. At this point, your program has already been corrupted. Look for the issue somewhere else. Valgrind would be a GREAT tool if you can try to compile under linux.
It seems that there is some sort of code optimization going on in your program. It is not always easy to debug optimized code step-by-step since the optimization may reorder instructions.
I cannot see why the fact that 'n' changes to an apparently uninitialized value would be the root cause of the problem, since 'n' is anyways no longer used in your function. Seems like the memory is simply been released as part of the optimization.
I have discovered my mistake. Earlier in the program I was comparing pointers, not what they were pointing at. A stupid mistake but one I wouldn't have spotted without a long debugging session. My boss explained that the information given at the bottom of Visual Studio whilst in release mode cannot be trusted. So to "debug" I had to use std::cout and check variables that way.
So here is the mistake in the code:
if(start > end){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}
Where start and end were defined earlier as:
int* start = new int[NofStacks];
int* end = new int[NofStacks];
And initialized.
Thanks to all those who helped and I feel I must apologise for the stupid error.
The Fix being:
if(start[i] > end[i]){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}

C++ - Vector iterator + offset out of range

I have looked at 10 or so answers about the same message but have yet to find my problem.
in level.h in the Level class:
std::vector<Bomb> m_bombs;
in level.cpp:
adding a bomb:
Bomb bomb;
bomb.owner = player;
bomb.power = power;
bomb.x = pos.x;
bomb.y = pos.y;
bomb.timer = 3.0f;
m_bombs.push_back(bomb);
checking bombs (every frame):
void Level::updateBombs(float dt)
{
for(int i = 0; i < m_bombs.size(); i++)
{
m_bombs[i].timer -= dt;
if(m_bombs[i].timer <= 0)
m_bombs.erase(m_bombs.begin() + i);
}
}
I am 100% sure the program crashes on the line where the erase function is called. I am able to output information from the vector which makes this way more confusing. The bombs are correctly in the vector. If I do m_bombs.remove_last() it removes the last element in the vector. Seem to just have problems with erase and begin().
You could fix your code by using erase-remove-idiom.
m_bombs.erase(std::remove_if(m_bombs.begin(), m_bombs.end(),
[](const Bomb& b){ return b.timer < 0.0f;}),
m_bombs.end());
Better split updateBombs function into two function:
updateBombs() does bomb timer update only
removeBombs() removes bombs which expired
Perhaps you can try erasing the vector backwards, e.g. if bomb index 3 and 5 to be erased, you remove the one with index 5 and then 3, because if you erase sequentially from 0 to N-1, by the time you erase index 3, then the index 5 will become index 4, which this can lead to out of bound when reaching the final step of the loop.
try this:
int pivot = 0
void Level::updateBombs(float dt)
{
for(int i = 0; i < m_bombs.size(); i++)
{
m_bombs[i].timer -= dt;
if(m_bombs[i].timer <= 0)
{
m_bombs.erase(m_bombs.begin() + i - pivot);
pivot++;
}
}
}
I had a similar problem when clearing or creating vectors.
The problem occurred because 2 different versions of dlls where being used at runtime. The clearing and creating took place when calling Open CV functions which seem to use different runtime libraries than my visual studio.
Changing visual studio finally fixed the problem (I tried a lot of old OpenCV builds before changing visual studio but to no avail). VS 2008 and 2013 didn't work, VS2010 did.
I would replace m_bombs.size() with an int variable of your own that you decrement after removing a bomb. I've personally had problems with .size(). It's supposed to return the number of elements in the vector but I've had an empty vector and .size() returned numbers greater than zero. Maybe trying this would help narrow down your problem.

Invalidating loop bounds

I've recently inherited a project primarily done in C++, so this is my first real exposure to it. I'm wondering if I may have a problem erasing a vector's elements from within a loop bounded by the vector's begin() and end().
Here's (essentially) what I've been trying to do:
for (vector<double>::iterator i = distance.begin(); i < distance.end(); i++) {
for (vector<double>::iterator j = i + 1; j < distance.end(); j++) {
/* code to assemble *i, *j, and some other values, say *x & *y
(also iterators) assumed to be in the distance vector */
vector< vector<double >::iterator remove;
remove.push_back(i); remove.push_back(j);
remove.push_back(x); remove.push_back(y);
sort(remove.begin(), remove.end());
for (int r = remove.size() - 1; r >= 0; r--) {
distance.erase(remove.at(r));
}
}
}
For what I'm testing it on, this appears to work. However, I'm concerned that's just because of a fluke and this solution shouldn't be used. Does distance.end() get reset at the beginning of each loop, or does C++ just check with the initial value?
for-loop will evaluate i < distance.end() on each loop. The problem is in distance.erase, it will invalidate i, so the result of i++ is undefined.
distance.end() is always accurate to the current state of the vector.
for() loops always re-evaluate the condition on every loop.