You have written all your code for a lab in C or C++, and when you run it all you get is "Segmentation fault", possibly followed by "(core dumped)". Now what? This writeup describes debugging programs.
Why does it say "segmentation fault (core dumped)"? "Segmentation" refers to memory being divided into regions and only certain numbers being valid memory addresses. A segmentation fault is just a generic way of saying something went wrong. The "core dumped" message means that a copy of memory was written to the disk. In theory you could load that memory into a debugger in order to figure out what went wrong. This is done on huge systems where reproducing faults is hard, it is not useful for small projects where it is easier to just re-run the code.
The first task is to determine what line of code was last executed; that is, where the error occurs. Between pipelined architecture and delayed fault detection (both important to high performance), the system cannot tell you what line was last executed successfully. Do not rely on stepping through code to find the error. Stepping works great when you are very close to the region of code with an error, but stepping through hundreds of statements to find a bug takes forever and often results in accidentally skipping over the line that contains the error.
If you are running your code in an integrated development environment (IDE), you are in luck: set breakpoints at key places in your code and see how far things go before the error happens. For example, set breakpoints just before reading any data, after reading the data, after computing results, and just before printing them. Then run in debugging mode and examine key data at each point to make sure things are going as expected. If the code gets to a breakpoint on line A but not on line B, add more breakpoints between A and B and rerun. Once you have it narrowed down to a few key lines, you can try stepping through.
If you are in an environment where you cannot set breakpoints, you can do the same with output messages. However, there is one key: send your messages to standard error. For example, add statements like
cerr << "At point A" << endl; ... cerr << "At point B" << endl;
In both cases, you will want to store your input in a file and use Run Configurations features to read your input from that file. Retyping input over and over is too error-prone, and if you change your input you might exercise a different error instead. Focusing on one error at a time is critical.
Minimizing your input is another key debugging trick. If you have a lot of data, determining if parts of your program are working is more difficult. So reduce your data using the following algorithm: