Active quantum error correction using qubit stabilizer codes has emerged as a promising, but experimentally challenging, engineering program for building a universal quantum computer. In this review the formalism of qubit stabilizer and subsystem stabilizer codes and their possible use in protecting quantum information in a quantum memory are considered. The theory of fault tolerance and quantum error correction is reviewed, and examples of various codes and code constructions, the general quantum error-correction conditions, the noise threshold, the special role played by Clifford gates, and the route toward fault-tolerant universal quantum computation are discussed. The second part of the review is focused on providing an overview of quantum error correction using two-dimensional (topological) codes, in particular, the surface code architecture. The complexity of decoding and the notion of passive or self-correcting quantum memories are discussed. The review does not focus on a particular technology but discusses topics that will be relevant for various quantum technologies.