Terminal Crashing on Switch statement

Hey all,
Wanted to make a guessing game based on a random number to be guessed by a player. I was able to compile successfully, but the terminal would crash after executing the line I indicate at in the code (about 8 lines in). Honestly, I do not know where to start with this issue and would like either a solution, or place to start troubleshooting the issue. For this code, I'm using 5.11 Dev-C++ to both compile and run code.
Thanks!
wsme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
	int guess, val1, dif, difval, attempts;
	
	cout<<"Choose a difficulty:";
	cout<<"\n 1. Easy   | 50  range";
	cout<<"\n 2. Medium | 100 range";
	cout<<"\n 3. Hard   | 150 range";
	cout<<"\nChoice> ";
	cin>>dif; //Crash after input
	
	switch (dif)
	{
		case 1:
			difval=50;
			break;
		case 2:
			difval=100;
			break;
		case 3:
			difval=150;
			break;
	}
	
	val1= rand () % val1 + 0;
	
	do
	{
		cout<<"\n\nInsert first guess : ";
		cin>>guess;
		
		if(guess>val1)
		{
			cout<<"Above";
			cout<<"\n\n";
		}
		if(guess<val1)
		{
			cout<<"Below";
			cout<<"\n\n";
		}
		attempts+=1;
	} while (guess!=val1);
	
	cout<<"Congratulations!";
	cout<<"\nYou won in  "<<attempts<<"  guesses"; //maybe add difficulty here as well?
}
Last edited on
To start troubleshooting the issue, explain why you claim the crash occurs at the point you say it does.

Take a careful look at the RHS of 29 (which can't be worked out).

Others:
- make an initial call to srand or you will get the same number every time;
- attempts hasn't been initialised to 0;
- it won't always be a "first" guess.
Last edited on
It looks like a possible divide by zero error.

There are a number of integers declared but not initialised.

At line 29
 
    val1= rand () % val1 + 0;

va1 has not been initialised, its value is garbage. The expression
rand () % val1
first calls the function rand(), then attempts to divide by val1. If val1 happens to be zero, that can give an error.

Actually, I think that line should use difval instead:
 
    val1 = rand () % difval;


On a related area, since difval was not assigned an initial value and the switch-case statement does not have a default clause, then difval may still contain garbage.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    switch (dif)
    {
        case 1:
            difval=50;
            break;
        case 2:
            difval=100;
            break;
        case 3:
            difval=150;
            break;
        default:
            difval=100;
    }


Also, the variable attempts has not been initialised, it contains garbage. It's a good idea to always
initialise variables before attempting to use them.

---------------------------------------------

How to start identifying problems such as this.
First compile with all warnings on, and pay attention to them.
From the Devc++ menu, select
tools->compiler options-> general
Check the box "add the following commands when calling the compiler:" and add the following:
-std=c++11 -Wall -Wextra -pedantic-errors


Secondly, you can use the debugger to step through the code line by line to identify the exact point at which it crashes (in this case, at line 29).


Thanks for the advice lastchance and Chervil!

I changed the number generator to:
 
val1= rand () % difval + 0;

and this resolved the issue.

Also, I'm about 2 months into learning C++ on my own from various online sites, so I wanted to clarify some parts of the responses.

lastchance:
The reason I believe it crashed was because the terminal would stop responding after providing a value for dif.

Take a careful look at the RHS of 29 (which can't be worked out).

I'm not familiar with the acronym "RHS". What is meant by this?

make an initial call to srand or you will get the same number every time;

Would you be able to instruct me on how to do this?


chervil:
Thanks for the in-depth assistance here. Unfortunately, the app I was using to learn from initially never taught initialization. I'll look for it as well, but would you mind linking me to the cplusplus site's guide on that to ensure I found the right one?

Agian, thanks guys!
Well there is a tutorial on this site, it depends on the individual whether it will give enough guidance.
http://www.cplusplus.com/doc/tutorial/

Here's some example code from the tutorial:
1
2
3
4
5
6
7
8
9
  // declaring variables:
  int a, b;
  int result;

  // process:
  a = 5;
  b = 2;
  a = a + 1;
  result = a - b;

There are arguments in favour of not declaring a variable until you are ready to assign an actual value. The above code would become:
1
2
3
4
  int a = 5;
  int b = 2;
  a = a + 1;
  int result = a - b;

That's just a hint to an approach which some people prefer.
Hello @wsme

It seems that you have got your program to work. To respond to your request for further clarification ...

- You are correct in the rand() % difval change (which was causing the crash); there is no purpose to the +0 though.

- To identify where a crash takes place then either use a debugger if one is available (which will tell you precisely which line is the culprit) or do a series of cout statements to confirm that you have got to strategic points in code (and may also be used to print out values of important variables). I'm afraid that assuming a crash takes place immediately after the last input or output statement is tempting but misses large amounts of code not involved in input/output (as here).

- RHS = right-hand side; occurs a lot in any topic involving equations; sorry if I assumed familiarity there.

- A single call of the form
srand(time(0))
(or similar) will set the "seed" for the initial position in the random-number sequence. Based on current time, it's fairly unrepeatable! You will need to #include <ctime> to use this. There should be single call only, before any calls to rand().
@Chervil
Thanks! I'll be sure to look into it more.

@lastchance
Removed the +0

Oh, that makes sense. I should have had more cout statements to check variables and program progression. Thanks for the advise in that regard.

Ah its fine, happy to know more acronyms

What does this command actually execute? I'm not familiar with srand() or time(). (I am certainly grateful to learn a way to improve the randomization though)
Last edited on
srand is "seed rand". To make a complex story short, random number generators are usually deterministic; that is, if you input the same "seed" you will get the same sequence of "random" values. For example if you put in 1 in the srand call, you would get the same values every time. Change that to 2, and you will get a different set of values but the same set each time, and so on.

Seeding with time makes it different every time because the seed is different each time you run the code. So to debug, you can put in a constant so you can get the same set each time and re-run it to find an issue. Then once satisfied, you can make it different every time it runs.

there is a newer random library with more features in new c++, srand is very old. rand() is linear congruential in most implementations which is very, very fast (its just a % statement) but very, very not-so-random.
Last edited on
A simple way to implement jonnin's idea.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifdef _DEBUG
const unsigned int SEED = 1; // or some other value
#else
const unsigned int SEED = static_cast<unsigned int>(time(nullptr));
#endif

int main()
{
  srand(SEED);

  for (int i = 0; i < 3; i++)
  {
    for (int j = 0; j < 3; j++)
    {
      cout << rand() % 10 << '\t';
    }
    cout << '\n';
  }
  system("pause");
  return 0;
}


Run the code a few times in Debug mode and you will always the same numbers.
When you run in iRelease mode you will get different numbers every time.
Topic archived. No new replies allowed.