Why do I get out_of_range with substr call? - c++

I was working on a competitive programming question. I wrote this question to count the number of "VK" substrings.
int count(string test) {
int answer = 0;
for (int i = 0; i <= test.size()-2; i++) {
if (test.substr(i,2) == "VK")
answer++;
}
return answer;
}
Why did I receive this error message when I try just "V" as the argument?
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr: __pos (which is 2) > this->size() (which is 1)
Shouldn't the statements in the for loop not execute because the loop's condition failed?

Shouldn't the statements in the for loop not execute because the loop's condition failed?
Yes, you are right, but the condition didn't fail!. test.size() is a std::size_t, an implementation defined unsigned type.
The key here is that it is unsigned, meaning that it can overflow without invoking undefined behavior. When you pass "V", test.size() is 1. Then, 1 - 2 is equal to -1, but this overflows as an unsigned number cannot take negative numbers! The result is a very large number.
So, the loop executes a lot more times than you would have thought, and that is were the std::out_of_range exception comes from: On the second iteration, you are already accessing index 1, which is out of range (as test has size 1).
You need to introduce a pre-condition check:
if (test.size() < 2)
return 0;

Related

wrote function to calculate set bits from 0 to n,

in this function i check if the no. is one less than the power of 2 and then make recursive calls for 2^b - 1 and n - 2^b(this call keeps happening till the no. here is one less than a power of 2)
now I know the code is wrong but why does it give segmentation fault.
int countSetBits(int n)
{
if (n == 0)
return 0;
int b = floor(log2(n));
if ( (n + 1) & n == 0 ) {
return (1<<b)* floor(log2(n + 1));
}
return (n - 1<<b + 1) + countSetBits(n - 1<<b) + countSetBits(1<<b - 1);
}
The infinite number of (recursive) function calls causes stack overflow. The program's stack has become too large and tries to "overflow" into the next memory segment. This is not allowed, and hence the segfault.
The reasons for the errors are two-fold:
You are using floating point numbers, in floor and log2. Those are imprecise and won't give you the exactness you need for this task.
You are left shifting your numbers (making them bigger). I didn't follow the logic you wanted, but usually, the approach is to take the least bits out and then right-shift the numbers (>>)
Lastly, either use a debugger, or introduce debug couts to see what your program is doing, that will make it overall much easier.

Addition Operation from ints in a String

I set up a string filled solely with numbers and using a for loop iterated through it in order to add them together mathematically (Wanted to see if the language would allow this), as a result I got some weird Numbers as the result. Can someone explain why this is happening?
int main()
{
std::string word = "2355412";
for (int i = 0; i<word.size(); i++){
int sum = word[i]+word[i+1];
std::cout << sum << std::endl;
}
return 0;
}
The code when run results in:
101
104
106
105
101
99
50
Due to the way I wrote my code I also believe that it should have resulted in an out of bounds error due word[i+1] on the final value resulting in the calling of a value that does not exist. Can someone explain why it did not throw an error?
The value you get is not what you expect because it is the sum of the ascii code corresponding to the characters you are summing, it's not converted into their value by default.
Also, as mentioned by other, string::operator[] doesn't check if you are trying to reach an out of bound value. In this case, you read 0 because you reached the string termination character \0 which happen to be 0.
it should have resulted in an out of bounds error
string::operator[] doesn't check bounds, it assumes you have. If you call it with an out of bounds index, the entire behaviour of your program is undefined, i.e. anything can happen.
It sounds like you want string::at, which does check bounds, and will throw std::out_of_range

Range checking for my remove function in c++

So I have a method in c++ that takes an array and removes a certain number of values in the array. The method removes the range of values from the starting value all the way up to but not including the end value. void dynamic_array::remove(int start, int end) {
The only problem I'm having is with the range checking. So I've set up a way to check to make sure the start and end values are not in the incorrect places however whenever I test the code, it appears that it doesn't catch the range exception. Here's the code that's supposed to check the exception:
if (not (0 <= ((start <= (end < size))))){
throw exception(SUBSCRIPT_RANGE_EXCEPTION);
}
you cannot use the notation 1 < x < 2 in c++ (or most languages). So you have to do each comparison separately. ie. (1<x) && (x<2) (brackets not really necessary here).
If you are interested, you actually can use the notation, but it means something different than you might think. It means that you first compare 1<x which gives either true (1) or zero(0) and then you compare this 1 or 0 with two.
It should be written
if(!(0 <= start && start <= end && end < size)){
throw exception
}
As i know, C++ can't understand the way you write it.
C++ does not work this way. The result of a single logical comparison is a boolean value. For example, the first comparison:
end < size
If this comparison is true, the result becomes a true value, which is for all practical purposes is 1. So, your expression now becomes, for all practical purposes:
if (not (0 <= ((start <= 1)))){
Which is already pretty much nonsensical, not to mention that there isn't a not operator in C++. Things pretty much roll downhill, from that point on.
You just need to make two logical comparisons: start < end, and end <= size. If you spend a few moments to think about it, you would realize this is all you need:
if (!(start < end && end <= size))

No checking condition in for loop C++

char i;
for (i = 1; i < 10, i++;)
{
cout << (i+1) << endl;
}
return 0;
I understand that for loop has the following syntax:
for(initialization; condition; increment)
{
}
As I run the debug, why it never checks the condition and it eventually stops at i = 0?
(Thank you Damien and Andars, I don't know why the "on purpose" statement was removed, but you interpret my question correctly. Could someone explain why the complier skips the condition before the comma, and why the loop stop at i = 0 instead of looping forever? Thanks!)
I believe he is indicating that he wrote the code that way on purpose.
To answer, i++ will always return true. The last value is the value that matters with comma separated statements, so the loop will not stop.
Edit for elaborations:
It isn't simply using a logical or, it disregards what is before the comma and only takes the last value. The value of anything non-zero is considered true, and since i starts at 1, and goes up, it will always be non-zero (until it overflows and wraps back around, which explains why i ends at 0).
If you say:
x = 4, 5, 6;
x will be equal to 6, the last value.
Change
for (i = 1; i < 10, i++;)
to
for (i = 1; i < 10; i++)
Change to
for (i = 1; i < 10; i++) //Notice correct placement of ;
It seems to me also that the code was written incorrectly on purpose. As others have mentioned, the comma operator will discard the value of the i<10 and only i++ will be evaluated as condition. This will return true until i overflows (values only from -127 to 127) and ends up at -1, when i++ will return 0 and the loop exits. Thus the final value for i will be 0.
Because you used the comma operator instead of a semi-colon

Floating Point Exception C++ Why and what is it?

I'm building a program for the Euler projects question 3, and while that might not really matter as a result I'm current trying to make this code take a number and test if it is prime or not. Now then before I get to troubleshoot the function it gives me the error "floating point exception" right after inputting the number. Here's the code:
int main()
{
int input;
cout << "Enter number: " << endl;
cin>> input;
int i = input/2;
int c;
for (i>0; i--;) {
c= input%i;
if (c==0 || i == 1)
cout << "not prime" << endl;
else
cout << "prime" << endl;
}
return 0;
}
so essentially why is it giving me a floating point exception and what does that even mean?
A "floating point number" is how computers usually represent numbers that are not integers -- basically, a number with a decimal point. In C++ you declare them with float instead of int. A floating point exception is an error that occurs when you try to do something impossible with a floating point number, such as divide by zero.
for (i>0; i--;)
is probably wrong and should be
for (; i>0; i--)
instead. Note where I put the semicolons. The condition goes in the middle, not at the start.
Lots of reasons for a floating point exception. Looking at your code your for loop seems to be a bit "incorrect". Looks like a possible division by zero.
for (i>0; i--;){
c= input%i;
Thats division by zero at some point since you are decrementing i.
Since this page is the number 1 result for the google search "c++ floating point exception", I want to add another thing that can cause such a problem: use of undefined variables.
Problem is in the for loop in the code snippet:
for (i > 0; i--;)
Here, your intention seems to be entering the loop if (i > 0) and
decrement the value of i by one after the completion of for loop.
Does it work like that? lets see.
Look at the for() loop syntax:
**for ( initialization; condition check; increment/decrement ) {
statements;
}**
Initialization gets executed only once in the beginning of the loop.
Pay close attention to ";" in your code snippet and map it with for loop syntax.
Initialization : i > 0 : Gets executed only once. Doesn't have any impact in your code.
Condition check : i -- : post decrement.
Here, i is used for condition check and then it is decremented.
Decremented value will be used in statements within for loop.
This condition check is working as increment/decrement too in your code.
Lets stop here and see floating point exception.
what is it? One easy example is Divide by 0. Same is happening with your code.
When i reaches 1 in condition check, condition check validates to be true.
Because of post decrement i will be 0 when it enters for loop.
Modulo operation at line #9 results in divide by zero operation.
With this background you should be able to fix the problem in for loop.