How To Debug
Author: Benjamin Qi
General tips for identifying errors within your program.
Resources | |||
---|---|---|---|
KACTL | things to try in an ICPC contest | ||
Errichto |
This module is based on both of these resources. I've included the content that is most relevant to USACO.
Pre-Submit
- Don't repeat yourself!
Java
Consider this example of swapping items in an array of integers.
public static void main(String[] args) {//swap first item with thirdint first = arr[0];int last = arr[2];arr[0] = last;arr[2] = first;//swap second item with fourthint second = arr[1];int secondLast = arr[3];arr[1] = secondLast;arr[3] = second;}
Hopefully you notice the unnecessary repetition in this code. Luckily, we can turn this into a function that takes in the two indicies of the array that we want to swap, like so.
private void swap(int[] arr, int i, int j) {int first = arr[i];arr[i] = arr[j];arr[j] = first;}public static void main(String[] args) {swap(arr, 0, 2);swap(arr, 1, 3);}
- Your code should be readable (to yourself at the very least). Variables should be given meaningful names.
- See style tips.
- Use plenty of print statements.
Wrong Answer
- Read the full problem statement again.
- Read your code again.
- Have you understood the problem correctly?
- Is your output format correct?
- Did you remove debug output before submitting?
- Add some assertions, resubmit.
- Are you sure your algorithm works?
- Go through the algorithm for a simple case / write some testcases to run your algorithm on.
- Do you handle all corner cases (such as ) / special cases?
- Any undefined behavior?
- Includes (but not limited to) uninitialized variables, array out of bounds, shifting int by bits, not returning anything from non-
void
functions. - Can result in different outputs locally / on the USACO server.
- Compiling with additional options can help catch these.
- C++ - can use
array::at
orvector::at
instead of[]
to throw exceptions when the index is out of bounds.
- Includes (but not limited to) uninitialized variables, array out of bounds, shifting int by bits, not returning anything from non-
- Any overflows or NaNs?
- Confusing and , and , etc.?
- Shadowed or unused variables?
- Compile with warning options.
- Write a test case generator and a (simpler) slow solution and compare the outputs
- See stress testing.
- You can compare against a model solution (if available).
- Rewrite your solution from the start.
- Don't delete your previous program. Make a new file! It's always possible that you might introduce more bugs.
- Use a debugger (if you're using an IDE).
- Set breakpoints to stop your program at certain lines.
- Step through lines one by one and watch how the values of your variables change.
- Probably slower than well-placed print statements ...
Of course, many of these are also relevant for RE / TLE.
Runtime Error
- Have you tested all corner cases locally?
- Any undefined behavior?
- Are you reading or writing outside the range of any vector?
- Any assertions that might fail?
- Any possible division by 0? (mod 0 for example)
- Any possible infinite recursion?
- Invalidated pointers or iterators?
- Are you using too much memory?
Time Limit Exceeded
- Do you have any possible infinite loops?
- What is the complexity of your algorithm?
- Avoid
vector
,map
. (usearray
s /unordered_map
) - Did you remove debug output before submitting (ex. are you printing a lot of information to
stderr
)?
Before Posting on the Forum
- Try everything above first.
- If you've found a small counter-test, you should be able to figure out why your code isn't working on your own via print statements.
- Provide a link to the problem (and the relevant module, if applicable).
- Include what you've attempted so far.
- If you have code, post it (formatted as described here).
- Add comments.
- If you know which part doesn't work, mention it.
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!