Simple Debugging
EXC_BADA_CCESS entails the use of a bad pointer, perhaps one pointing into memory that isn’t legal for you to read or write to. (The 64-bit virtual-memory management on OS X and modern iOS is set so any address that might be derived from a 32-bit integer is illegal, making it harder to cross ints and pointers.) Reexamine the line in main that crashed the application and allow a scale to fall from your eyes:
nArgs = scanf("%d %d %d %d %d", &comps, &atts, &yards, &TDs, INTs);
scanf collects values through pointers to the variables that will hold them. This call does that for all values except INTs, which is passed by value, not by reference. One of the warnings I had you ignore said exactly that: “Format specifies type ‘(int )’ but the argument has type ‘int’.” Simply inserting an &
nArgs = scanf("%d %d %d %d %d", &comps, &atts, &yards, &TDs, &INTs);
should cure the problem. Sure enough, running passer-rating again shows the crasher is gone:
comps, atts, yards, TDs, INTs: {10 20 85 1 0 Rating = 89.4 comps, atts, yards, TDs, INTs: <∧D>
With the ∧D keystroke, the input stream to passer-rating ends, the program exits, and the Debug area closes.
You ordinarily wouldn’t want to run or debug a program under Xcode if another is running. Instead, you’d like the incumbent app to clear out. There are four ways to do this.
- Simply let the app exit on its own, as you did when you used ∧D to stop passer-rating, or would by selecting the Quit command in an OS X application. But this doesn’t work for iOS apps, which in principle never quit. You’ll have to use one of the other techniques.
- Click the Stop button in the toolbar.
- Select Product → Stop ( period).
Tell Xcode to run an application, the same or a different one, and click Stop in the alert sheet that appears. See Figure 3.4.
Figure 3.4 When you tell Xcode to run an application while it already has an application running, it displays a sheet asking what you want to do with the existing app. Normally, you’d click Stop, but there is also the option to Add the new instance to run concurrently with the old one.
That alert sheet also offers an Add button, which will run and debug the new process without quitting the old one. Xcode will start a new execution context: You can switch between them using the jump bar at the top of the Debug area, and the Stop button in the toolbar becomes a menu you can use to select which instance to stop.
For the moment, you’re done: The scanf call will return fewer than five inputs if the standard input stream ends. You end it as you would in a terminal shell, by pressing ∧D.