StackOverflow Frequently Answered C++ Questions

This is the F(requently)A(nswered)Q(uestions) page (not to be confused with the C++ FAQ) for the C++ tag on StackOverflow. These questions come up every few hours on StackOverflow. If you are new to C++ and are about to ask a question, please read through these to make sure your problem is not one of them.

I'm getting some weird errors, can you help me?

  • No, we definitely cannot help you because we don't know what the errors are. When you have any error, ALWAYS POST THE ERROR AND THE CONTENTS OF THE LINE ON WHICH THE ERROR IS OCCURRING. If you don't, you'll only delay your question getting answered.

I get errors when I try to read in a string variable from a stream (like cin)

  • Did you #include <string>?

See

When printing/working with a const char* style string, garbage shows up at the end and/or my program crashes

  • First of all, consider using std::string if you are not doing this to learn how to work with pointers. You'll save a lot of time.
  • The C-string is probably not NUL-terminated. C-strings don't store the length in them, so to find out how long they are, a function must walk through the entire string to find a NUL (0) byte. If you forgot to add one, the function will go past the end of the array and cause undefined behaviour. Here are some correct and incorrect examples of using C-strings:
char array[] = {'a', 'b', 'c'};    // WRONG: No NUL terminator
char array[] = {'a', 'b', 'c', 0}; // RIGHT
 
const char* array = "hello";  // RIGHT: string literals have an automatic NUL at the end
char array[] = "hello";       // RIGHT: same as above
 
char array[3];
array[0] = 'a';
array[1] = 'b';
array[2] = 'c'; // WRONG: an array of length 3 can only hold 2 characters (because the NUL-terminator takes up one space at the end)

See

A C-string manipulation function I wrote crashes for no apparent reason

  • Make sure you are not calling the function with a string literal. You are not allowed to modify the contents of string literals; doing so causes undefined behaviour. Often in the real world, these arrays are stored in the compiled program's binary image, often in a section of memory that only has read permissions, not write permissions (if you don't understand that, it's ok, just move on). You need to create the string on the stack:
void changeACString(char* str) {
    str[0] = 'a';
}
 
char* strptr = "hello"; // a proper NUL-terminated C-string literal, residing in read-only memory
changeACString(strptr); // WRONG: changeACString modifies the memory of the string it receives and str points to a string literal; Undefined Behaviour
 
char strarr[] = "hello"; // initialising a *local* array with a C-string; the array is on the stack
changeACString(strarr);  // RIGHT: changeACString will modify the local array which is fine

Note that the first example char* strptr = "hello"; shouldn't even compile because "hello" is a char const[6] which is not convertible into a char* but only to a const char*; however, some compilers wrongly allow this faulty behaviour.

See

I get linker errors just because I used a static variable in my class

  • You have to define the variable; the name of the variable in the class definition is just a declaration, similar to a prototype of a function. To define a static variable, do the following:
// this would be in the header
class MyClass {
     static std::vector<int> someStaticVariable; // declaration
};
 
// and this would be in *one* .cpp file
std::vector<int> MyClass::someStaticVariable; // and optionally initialise it with = something
//^^^^^^^^^^^^^^ ^^^^^^^  ^^^^^^^^^^^^^^^^^^
//     (a)         (b)            (c)
 
// (a) variable type
// (b) class name
// (c) variable name

If your class is a template class, you have to do this:

template<typename T, typename U>
class MyClass {
     static std::vector<int> someStaticVariable; // declaration
};
 
// for tempates, the definition must be in the same file as the declaration, see the entry on #includes at the bottom of header files
template<typename T, typename U>
std::vector<int> MyClass<T, U>::someStaticVariable;

See

Why do I see an #include at the bottom of this header file (that contains templates)?

  • Compilers require the definitions of templates to be in the same file as the declaration. This means that you can't seperate template classes or functions into .h and .cpp files. To get around this restriction while still making the interface and implementation visually seperate and in seperate files, a common ploy is to #include the implementation file at the bottom of the interface file. The preprocessor will do what amounts to a copy-and-paste of the implementation file into the interface file, satisfying the compiler.

See

I'm using a Standard Library container to store an array, why —

  • Stop right there, you can't use ST(andard)L(ibrary) containers to store arrays because the elements stored in such containers must be assignable, and arrays are not assignable. Consider using std::vector or if you have C++11, std::array.

See

I'm doing stuff with pointers and junk is showing up and/or my program is crashing/I am returning a reference from a function and when I try to print it, garbage shows up

  • Be sure you are not returning a pointer or a reference to a local variable (including automatic arrays). These variables are destroyed when the function returns. Note that you can return a pointer or reference to a static variable and that's fine.

How can I find the length of an array?

  • You can use std::end(array) - std::begin(array) to find the length of an array. However, after you pass the array to a function, the name decays to a pointer and you lose the size information. The only way to know the size of such an array is to
    • Ditch raw arrays and use std::array or std::vector (recommended)
    • pass the size to the function in another variable
    • put a special value at the end of the array and do a linear search for it to determine where it ends, like C-strings do (but this should be the very last resort)

See

What is the difference between int* i, int * i, and int *i?

  • There is no difference.

See

What is the difference between i++ and ++i?

  • The former is post increment, and the latter is pre increment. Post increment increments i and evaluates to the previous value of the variable.
int i = 0;
 
cout << i++; // prints 0
cout << i;   // prints 1

Pre increment increments i and evaluates to the new value of i.

int i = 0;
 
cout << ++i; // prints 1
cout << i;   // prints 1

See

What does i++ + ++i do/cout « ++i « i « i++ doesn't print what I expect/how many operators can you combine in a row?

  • Doing that invokes undefined behaviour; anything is allowed to happen. Don't ever do it and don't ask questions about it and waste everyone's time.

See

What is this "undefined behaviour" that everyone keeps mentioning?

  • It means that you are doing something that the C++ Standard has declared should never be done. If you do cause behaviour, the results can legally be _anything_; your program can appear to work, it can work sometimes and fail other times, it can crash, it can erase your hard drive, launch the missiles, or buy pizza with your credit card.

See

I declared a variable (like this: int i;) and I'm getting garbage when I print it. Why?

See

  • Needs references

Why is the sizeof my struct larger than the sum of the sizes of its members?

  • The compiler is free to introduce padding (unused space) before, between, and after the members of a structure.

See

Why am I getting compiler errors when I try to return a type that is a typedef inside a template?

  • You have to use ‘typename` before the type name or the compiler will think it’s a variable. For example:
template<typename T>
struct MyClass {
    typedef T::type TType;
};
 
template<typename T>
typename MyClass<T>::TType Function() {
//^^^^^^
    ...
}

See

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License