I sometimes get this type of errors. My question is, is there a way to find out information about when and where(which line) exactly this error occurs? I'm on ubuntu linux 14.04. Using sublime and g++.
Here is my current code. I get a floating point exception in this. It takes 2 vectors and prints the numbers that are divisible by every element of the first set and can divide every element of the second set.
Posting the code is kinda irrelavant to the topic but it forced me to find a decent way to debug the mentioned error types. This is my first time asking a question here, go easy on me.
int main()
{
vector<int> firstVector;
vector<int> secondVector;
firstVector = {2,4};
secondVector = {16,32,96};
auto it = firstVector.begin();
for (int i = 1; i <= 100; ++i)
{
it = firstVector.begin();
for (; ; ++it)
{
if(i%(*it)!=0)
break;
if(it==firstVector.end())
{
it=secondVector.begin();
while(it!=secondVector.end())
{
if((*it)%i!=0)
{
it=firstVector.begin();
break;
}
it++;
}
}
if(it==secondVector.end())
break;
}
if(it==secondVector.end())
cout << i << endl;
}
return 0;
}
I guess there is a problem in iteration over firstVector and secondVector. In second loop:
auto it = firstVector.begin();
for (; ; ++it)
{
it is iterator for firstVector. But in the next loop:
it=secondVector.begin();
while(it!=secondVector.end())
{
it becomes iterator for the secondVector. Iteration over it continues in the outer for loop after this while loop. You increment ++it and access elements if(i%(*it)!=0) at and after the .end() element. This leads to UB:
This element acts as a placeholder; attempting to access it results in undefined behavior.
This question is kind of a two-parter. Since Nikita already addressed your code...
My question is, is there a way to find out information about when and where(which line) exactly this error occurs?
Use gdb name-of-executable to debug on Linux. Simply run and the program will break when a seg fault occurs or, I believe, a fatal exception is thrown. It will tell you the file name and line number.
You can also look up more gdb commands, like here: http://www.yolinux.com/TUTORIALS/GDB-Commands.html
Related
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);
Question is quite simple, how do I print a deque, but from behind. Example: I have a deque with elements {5,4,3,2,1}. I want to print that deque, but starting from the last element, so I should have someting like 1 2 3 4 5 on my screen.
Usual for(int i(deque.size()); i > 0; i--) loop obviously won't work.
Little intro to the program. It finds numbers whose sum is even or odd, and sorts them into two different deques that are to be printed on screen.
This is the code that works for 'usual' printing. But my task says to print them backwards.
Oh, and the elements are added to the deque using push_front function. And no, I'm not allowed to use push_back to 'fix' it.
void PrintDek(Dek v4) {
for (int i(0); i < v4.size(); i++) {
std::cout << v4[i];
if (i != v4.size() - 1) std::cout << ",";
}
}
If some of you feel the need for the whole program's code, I'll edit my post.
You can use reverse iterators. See http://en.cppreference.com/w/cpp/container/deque/rbegin.
for(auto iter = deque.rbegin(); iter != deque.rend(); ++iter) {
// do stuff
}
So after seeing my code after a good few hours of sleep (this question was posted after 2AM according to my timezone), I've come to realize what my mistake was. By using deque.size() and moving all the way up to the value that the size() function returns, I was actually going out of range, accessing forbidden parts of memory.
Simple deque.size()-1 now works. So the loop would look like this for(int i(deque.size()-1); i >= 0; i--).
I have been trying to use std::list, however my work has been sabotaged by following error:
Debug Assertion Failed!
Program: C:\Windows\system32\MSVCP120D.dll
File: c:\program files (x86)\microsoft visual studio 12.0\vc\include\list
Line: 289
Expression: list iterators incompatible
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
I have searched a little (a few hours in fact), yet nothing has solved my problem.
Error shows itself in following function:
void Plane::createFrame(){
for( int i = 0; i < 400; i++ ){
frame[i] = '_';
}
for (std::list<Unit>::iterator iterator = units_container.begin();
iterator != units_container.end(); ++iterator) {
iterator->draw(frame, 20);
}
}
Where draw function looks like this:
void Unit::draw( char(&world)[400], int width ){
world[ position ] = avatar;
}
Another interesting thing is thing is that I managed to "contain" this error:
void Plane::createFrame(){
for( int i = 0; i < 400; i++ ){
frame[i] = '_';
}
for (std::list<Unit>::iterator iterator = units_container.begin();
iterator != units_container.end(); ++iterator) {
if( iterator->getPosition() < 0 ||
iterator->getPosition() > 399 ){
break;
}
iterator->draw(frame, 20);
}
}
Changed createFrame() seems immune to previous error.
If I change my code same error my occur in different places (change is necessary, though. Right now it is always createFrame() that shows error). It always show within almost the same for maybe with different function being invoked.
createFrame() is being invoked in a loop. Error usually happens after 100 lap. Changed createFrame() uses break; randomly, however error never shows.
There are no other threads that could access list.
I'm using erase() but error doesn't seem connected in any way.
I hope I didn't miss anything obvious, but now I can't really be sure.
Thanks for your time.
You have an array which is passed to Unit::draw as char(&world)[400], and you are writing into index position of that array.
If position is not between 0 and 399, this will result in undefined behavior. This can cause various symptoms: your code may crash, it may work incorrectly, or it may display seemingly unrelated error messages such as the one you are getting about iterators.
When you added the check that position is between 0 and 399, the error stopped happening here. You say that it now happens elsewhere, so you should check if there is any out-of-bounds array access there (or any other kind of undefined behavior). It may be best to ensure that position doesn't get assigned an invalid value in the first place.
I have a vector<int> called pitches. I'm getting periodic bad access on the last line below:
int play = 0;
bool didFind = 0;
vector<int>::const_iterator iterator;
for (iterator = pitches.begin(); iterator != pitches.end(); ++iterator) {
if (*iterator > lastpitch) { // lastpitch is an int
didFind = 1;
play = *iterator;
break;
}
}
if (!didFind) play = *(pitches.begin()); // this line gives me bad access
I had previously tried *pitches.begin() on the last line but that always provided bad access and I understand that now. But while I get it less often now, this play=*(pitches.begin()); is still doing the same occasionally. I cannot see anything in the above that would cause that, any suggestions appreciated.
If pitches vector has size 0, the things inside
for (iterator=pitches.begin();iterator!=pitches.end();++iterator)
doesn't get executed and therefore didFind=0.
The statement inside if is evaluated. Yet pitches is empty means pitches.begin()==pitches.end(). Dereferencing a pitches.end() is to access out of bound and therefore gives bad access.
This piece of code gives me an error
struct state{
int time_taken;
vector<int>time_live;
string loc_name;
vector<int>loc;
};
for(int u=0;u<(A[start].loc.size());u++)
{
l=A[start].loc[1];
if(A[l].time_taken < min_time)
{
min_time=A[l].time_taken;
finish = l;
}
}
This gives a segmentational fault .
Firstly, if A[start] is out of range then you may get a problem, which may or may not be a seg fault, depending on what A is.
Secondly, in the loop you have A[start].loc[1], which will be out of range if A[start].loc is empty. Did you mean loc[u]?
As from the above code.
before for loop make sure
start < A.size();
Inside for loop
l = A[start].loc[u]; // instead of 1
and before
if(A[l].time_taken < min_time)
check
if (l < A.size())
I like Anthony Williams's first point, but my guess is that A[l] is out of range.
Perhaps you could try to access A by using A.at(start) if this is out of range it will now throw an exception as opposed to segfaulting