Getting Help

For C++ programming help, first look over the common mistakes listed below, then ask instructor/TAs.
The advice on this page is divided into scenarios:

Compilation errors

Active the Error List window
Click 1st error, then press F1 for help.
Word of advice: only fix the first error, then try compiling again. The first error is always your fault, but subsequent errors are often just the compiler being confused by the first error.

When there is a C++ compilation error, you'll want to see the Error List window. (The Error List is not visible by default, so go to Tools–>Options and activate it as shown.) Once you see the Error List, double click the first error. If you don't understand what it means, select the error and press the F1 key to get Microsoft's "help" on that specific error.

Microsoft's documentation can be confusing because it is written for expert C++ programmers. You can also read following advice on errors that CS 1037 students typically encounter.
Error C1075
Error C2059
Error C2065
Error C2143
Error C2146
Error C2228
Error C2236
Error C2275
Error C2440
Error C2601
Error C2628
Error C2819
Error C3861
Error C4430
Error LNK2001
Error LNK2019

Error C2065: 'name': undeclared identifier
Error C3861: 'name': identifier not found
You tried to use a variable/function using a name (identifier) that the compiler doesn't recognize, e.g. you mis-spelled or forgot to declare the variable:
void main() {
    x = 5;           // ERROR: 'x': undeclared identifier; need to declare x.
    int y = yearr(); // ERROR: 'yearr': identifier not found; maybe year()?
}

Error C2275: 'type': illegal use of this type as an expression
You used a type name as though it were a variable name:
struct point { int x,y; };
int x = point.x;     // ERROR: 'point' is not a variable, it's a variable *type*

Error C2164: syntax error ';' before identifier 'name'
A few situations can cause this. You may have mis-spelled a type name (e.g. innt instead of int) and so the compiler got confused:
struct point { int x,y; };
Point p;     // ERROR: compiler doesn't know what 'Point' is; should be 'point'

Error C2440: cannot convert from 'type1' to 'type2'
You tried to assign a=b when a and b are of completely different types:
int   x = 0; // OK: 0 is understood to be of type 'int'
int*  y = 0; // OK: 0 is understood to be of type 'int*'  (null)
char* z = 0; // OK: 0 is understood to be of type 'char*' (null)
x = y;       // ERROR: cannot convert from 'int*'  to 'int'
y = x;       // ERROR: cannot convert from 'int'   to 'int*'
y = z;       // ERROR: cannot convert from 'char*' to 'int*'
This can also happen when passing function arguments or return values:
int year() {
    return "2010"; // ERROR: cannot convert from 'const char [4]' to 'int'
}

void draw_point(point p);
void main()
{
    int x = 50;
    draw_point(x); // ERROR: cannot convert parameter 1 from 'int' to 'point'
}
Another cause is forgetting to use () when calling a function. This mistake gives a really confusing error message, but is easy to fix if you spot it. Supposing we have function year():
int y = year;      // ERROR: cannot convert from 'int (*)()' to 'int'

Error C2628: 'type1' followed by 'type2' is illegal
Error C2236: unexpected 'class-key' 'identifier''
You probably forget to put a ';' in a struct/class declaration:
struct point { int x,y; }; // OK
struct point { int x,y; }  // ERROR: declaration of 'point' must end with ;

Error C2143: missing ';' before '}'
You forget to put a ';' after the last statement inside some { } block:
struct point { int x,y  }; // ERROR: declaration of 'x,y' must end with ;
int five() { return 5 }    // ERROR: forgot to put ; after 5
if (ok) { cout << "ok" }   // ERROR: forgot to put ; after "ok"

Error C1075: end of file found before the left brace '{' was matched
Error C2601: local function definitions are illegal
You have more { than }, meaning you forgot to close one of your scopes:
int min(int a, int b) {
    if (a < b) { 
        return a;
    return b;
}              // compiler sees '}' as matching (i.e. closing) the 'if' block

void main() {  // ERROR C2601: compiler sees main() as though inside min()
}      
               // ERROR C1705: end of file before all '{' were matched

Error C2059: syntax error
Lots of things can cause this. For example, you may have an extra } somewhere:
int min(int a, int b) {
    if (a < b)
        return a;
    }            // oops! this '}' closes the function!
    return b;    // ERROR: syntax error 'return'
}                // ERROR: syntax error '}'

Error C4430: missing type specifier
Either you declared a global function/variable without a type:
x = 5;                // ERROR: should be declared as "int x = 5;"
five() { return 5; }  // ERROR: should be declared as "int five()"
Or you have an extra '}' somewhere and the compiler is confused about scope; see Error C2059.

Error C2819: type does not have overloaded member 'operator ->'
You accessed a member using '->' when you should've used '.'.
point p;
p->x = 0;     // ERROR: 'p' is not a pointer, so use 'p.x'

Error C2228: left of '.name' must have class/struct/union
You accessed a member using '.' when you should've used '->'.
point* q = &p;
q.x = 0;      // ERROR: 'q' is a pointer, so use 'q->x'

Error LNK2001/LNK0019: unresolved external symbol 'name'
You declared a function or variable but you forgot to define it one of the .cpp files. This can also happen if you accidentally type the wrong name for the function.
void hello();     // Declare 'hello' function (often in a .h file)

void main() {
    hello();      // ERROR: unresolved external symbol 'void hello(void)'
}

void hallo() {         // Rename this 'hello' and it will work, as long as 
    cout << "hello";   // it appears in any .cpp file in to your project
}

Run-time errors

In the vast landscape of bugs, crashes are the closest thing you have to a friend. A crash is proof that you've made a mistake, and its location (in your code) is important information.

In C/C++ programming, the most common types of crashes are:
Oy! Writing to address 0 is an "Access violation."
So, on some level these crashes are the same, but they can be caused by a variety of high-level and low-level mistakes.

Here are some typical mistakes, along with buggy code samples to help explain:

Loop goes out of range
Code that crashes on delete. Can you spot the bug?
Loops must be programmed very carefully, even by experts; incorrect loops are a huge, huge source of bugs. If an array b has 10 items, then the first item is b[0] and the last item is b[9]. If your code somehow asks for b[-1] or b[10], then you have a dangerous bug. When you see b[i] you should think "that's the (i+1)'th item in the array".

Uninitialized variable
Never read a variable's value until you know it's been set beforehand. In the following example, there are two uninitialized variables.
int grades[80];           // grades[0..79] = ???
int i = 0, j;             // i = 0, j = ???
int grade_i = grades[i];  // DANGER: grade_i = ???
int grade_j = grades[j];  // CRASH:  grade_j = grades[???]
Reading grades[0] isn't technically a crash — you own that memory so you can read it if you like — but the debugger will still warn you that it's a stupid thing to do. Reading grades[j] is a real crash because it accesses some random memory.

Pointers are a type of variable that should always be initialized. If you don't have something to point at right away, always initialize to NULL (zero):
int* ptr;        // ptr = ???
if (ptr != 0)    // Useless test, since ptr is probably not 0
    *ptr = 123;  // CRASH: *(???) = 123

Uninitialized data member
Data members are just variables, so they need to be initialized too! The following class has such a bug:
class array_of_int {
public:
    void push_back(int item) { m_items[m_size++] = item; }
private:
    int m_size;
    int m_items[50];             // Stores up to 50 integers
};

void main() {
    array_of_int temperatures;
    temperatures.push_back(22);  // CRASH: grades.m_items[???] = 22
}
The solution here is to provide a constructor that initializes m_size:
class array_of_int {
public:
    array_of_int() { m_size = 0; }  // Fixed the bug!
    ...

NULL pointer dereference
ptr1 points to x, ptr2 is NULL.
A "NULL pointer" is a pointer variable that's been set to address 0. Address 0 is used as a way of saying "this pointer doesn't point at anything right now." Accessing the memory at address 0 will always cause an access violation (crash).
int* ptr = 0;  
*ptr = 123;     // CRASH: tried to write '123' to memory location 0

Dangling pointer
A pointer is 'dangling' if it points to an address that is no longer a valid variable, i.e. if you dereferenced the pointer, the program would crash immediately or be corrupted (crashing later):
void main()
{
    int* grades = new int[50];    // 'grades' becomes valid pointer.
    delete [] grades;             // 'grades' becomes dangling pointer! Careful...

    for (int i = 0; i < 50; ++i)  // You can accidentally read/write a dangling pointer
        grades[i] = 0;            
}                                 // Until program exits -- heap corruption detected!

Logic mistakes

If you make a "logic error" it means you didn't correctly plan or predict the program execution. The program still runs, but it computes the wrong thing somehow. We only list a few of the most common mistakes:

Using = when you meant ==
When writing if-statements, be extra careful to use == (test equality) and not just = (assign value). Here's an example of such a bug:
int speed = 0;
if (speed = 0)
    cout << "speed is zero!";   // This line never runs!

Modifying a list within a loop
You have to be very careful programming a loop that inserts/erases elements. For example, the loop below has a classic logic bug:
void erase_perfect_grades(array_of_int& grades)
{
    for (int i = 0; i < grades.size(); ++i) // Buggy loop
        if (grades[i] == 100)
            grades.erase(i);
}
If grades contained intitial values {85,100,100,60} then after returning it will contain {85,100,60}. Why wasn't the other 100 erased? Because erase(i) shifts all the items after i downwards, so that item i+1 now occupies slot i and so on. Correct code is as follows:
void erase_perfect_grades(array_of_int& grades)
{
    for (int i = 0; i < grades.size(); )    // Correct loop
        if (grades[i] == 100)
            grades.erase(i);
        else
            ++i;    // Only do ++i if item is not erased
}

Copied object when you should've referenced it
Some variables are naturally safe to copy, while other (usually larger) variables represent a unique entity in the program (for example, the player's current location/state) and so there should only exist one copy of that variable.
struct rectangle { int x,y,wd,ht; };

void grow_rect(rectangle rect, int amount)  // Grow size of a rectangle by 'amount'
{
    rect.wd += amount;
    rect.ht += amount;
}

void main()
{
    rectangle mario_hitbox = { 0,0,50,100 };
    grow_rect(mario_hitbox,10);   // Doesn't modify mario_hitbox!
    draw_rect(mario_hitbox);      // Draws rect of size 50x100, not 60x110.
}
The above code could be fixed by replacing rectangle rect with a reference rectangle& rect or, with a few more changes, a pointer rectangle* rect would work too. See lecture notes on references for more examples.

You're doing it wrong!

Here are some examples of the wrong way and right way to do things in C++. The symbol T represents a class name (e.g. string, array_of_int, etc). Make sure none of the "wrong" examples appear in your assignments, or you'll lose marks! The list will grow throughout the course, so check back before each assignment.

Creating & destroying variables
wrong
{
    T obj;
    obj.~T(); // Destructed once.
}             // Destructed twice!
right
{
    T obj;
}             // Destruct once.

Never call a destructor explicitly! Variables on stack are destructed when they go out of scope (example above), and variables in heap are destructed by the delete function.
wrong
T* p = new T[5]; // p[0..4] constructed.
delete p;        // Only p[0] destructed!
right
T* p = new T[5];
delete[] p;      // p[0..4] destructed.
If you allocate an array of items with new T[] then you must deallocate with delete[]. In other words, C++ unfortunately makes you responsible for remembering which pointers point to a single object via new T and which point to an array of objects via new T[].
wrong
ptr = 0;      // Memory leak!
delete ptr;   // Does nothing.
right
delete ptr;   // Free memory.

The above example assumes that ptr points to a single object and we want to destroy the object (i.e. free the memory it uses). To destruct the object and free its memory, just call delete. You can point ptr at something else afterwards, if you like (e.g. to NULL).