Chapter 17 vector and Free Store. Bjarne Stroustrup

Similar documents
Chapter 17 vector and Free Store

Chapter 17 vector and Free Store

Abstract. Vector. Overview. Building from the ground up. Building from the ground up 1/8/10. Chapter 17 vector and Free Store

vector and Free Store

Vector and Free Store (Pointers and Memory Allocation)

The vector Class and Memory Management Chapter 17. Bjarne Stroustrup Lawrence "Pete" Petersen Walter Daugherity Fall 2007

Pointers and Memory 1

Implementing vector<>

Chapter 18 Vectors and Arrays [and more on pointers (nmm) ] Bjarne Stroustrup

Managing Memory. (and low level Data Structures) Lectures 22, 23. Hartmut Kaiser.

Vector and Free Store (Vectors and Arrays)

Chapter 19 Vector, templates, and exceptions

PIC 10A Pointers, Arrays, and Dynamic Memory Allocation. Ernest Ryu UCLA Mathematics

Chapter 5 Errors. Bjarne Stroustrup

INITIALISING POINTER VARIABLES; DYNAMIC VARIABLES; OPERATIONS ON POINTERS

CSC 1600 Memory Layout for Unix Processes"


CS107 Handout 08 Spring 2007 April 9, 2007 The Ins and Outs of C Arrays

COMP6771 Advanced C++ Programming

EL2310 Scientific Programming

Exercise 6.2 A generic container class

Pointers. A pointer value is the address of the first byte of the pointed object in the memory. A pointer does not know how many bytes it points to.

The issues. Programming in C++ Common storage modes. Static storage in C++ Session 8 Memory Management

C++ Programming Lecture 4 Software Engineering Group

C++ for Java Programmers

Chapter 5 Errors. Hyunyoung Lee. Based on slides by Bjarne Stroustrup.

CSCI-1200 Data Structures Spring 2016 Lecture 6 Pointers & Dynamic Memory

Pointers. 1 Background. 1.1 Variables and Memory. 1.2 Motivating Pointers Massachusetts Institute of Technology

Pointer Basics. Lecture 13 COP 3014 Spring March 28, 2018

static CS106L Spring 2009 Handout #21 May 12, 2009 Introduction

G52CPP C++ Programming Lecture 16

Arrays and Pointers. Overview. Arrays Introducing Pointers C-Style Character Strings Multidimensioned Arrays

Software Design and Analysis for Engineers

Short Notes of CS201

RAII and Smart Pointers. Ali Malik

Object Oriented Software Design II

CS201 - Introduction to Programming Glossary By

Pointers and References

Lecture Topics. Administrivia

Structure of Programming Languages Lecture 10

Casting in C++ (intermediate level)

In Java we have the keyword null, which is the value of an uninitialized reference type

G52CPP C++ Programming Lecture 20

Lecture Notes on Memory Layout

CSE 374 Programming Concepts & Tools. Hal Perkins Spring 2010

377 Student Guide to C++

Consider the above code. This code compiles and runs, but has an error. Can you tell what the error is?

Limitations of the stack

Proposal to Acknowledge that Garbage Collection for C++ is Possible X3J16/ WG21/N0932. Bjarne Stroustrup. AT&T Research.

CE221 Programming in C++ Part 2 References and Pointers, Arrays and Strings

CS93SI Handout 04 Spring 2006 Apr Review Answers

Chapter 1 GETTING STARTED. SYS-ED/ Computer Education Techniques, Inc.

Chapter 3 Objects, types, and values. Bjarne Stroustrup

Arrays. Returning arrays Pointers Dynamic arrays Smart pointers Vectors

Chapter 21a Other Library Issues

QUIZ How do we implement run-time constants and. compile-time constants inside classes?

CMSC 330: Organization of Programming Languages

Programs in memory. The layout of memory is roughly:

CSCI-1200 Data Structures Fall 2017 Lecture 5 Pointers, Arrays, & Pointer Arithmetic

CMSC 330: Organization of Programming Languages

Chapter 1 Getting Started

Dynamic Allocation in C

CS162 - POINTERS. Lecture: Pointers and Dynamic Memory

Assignment 1: grid. Due November 20, 11:59 PM Introduction

A brief introduction to C++

C++ Programming Lecture 7 Software Engineering Group

Pointers and Terminal Control

Memory Corruption 101 From Primitives to Exploit

CSE 374 Programming Concepts & Tools. Hal Perkins Fall 2015 Lecture 19 Introduction to C++

A Generic Non-intrusive Smart Pointer Implementation

18-642: Code Style for Compilers

Arrays in C C Programming and Software Tools. N.C. State Department of Computer Science

CS11 Advanced C++ Fall Lecture 7

CS61C Machine Structures. Lecture 4 C Pointers and Arrays. 1/25/2006 John Wawrzynek. www-inst.eecs.berkeley.edu/~cs61c/

CMSC 330: Organization of Programming Languages. Memory Management and Garbage Collection

Introducing C++ to Java Programmers

CS201 Some Important Definitions

ALL ABOUT POINTERS C/C++ POINTERS

Programming Languages. Streams Wrapup, Memoization, Type Systems, and Some Monty Python

CS 31: Intro to Systems Pointers and Memory. Kevin Webb Swarthmore College October 2, 2018

Reminder: compiling & linking

o Code, executable, and process o Main memory vs. virtual memory

Programming in C and C++

CA31-1K DIS. Pointers. TA: You Lu

18. Dynamic Data Structures I. Dynamic Memory, Addresses and Pointers, Const-Pointer Arrays, Array-based Vectors

CSCI-1200 Data Structures Fall 2017 Lecture 10 Vector Iterators & Linked Lists

Heap Arrays. Steven R. Bagley

Modern C++ for Computer Vision and Image Processing. Igor Bogoslavskyi

Standard-Library Exception Safety

CSE 303: Concepts and Tools for Software Development

Pointers in C/C++ 1 Memory Addresses 2

CMSC 341 Lecture 2 Dynamic Memory and Pointers

These new operators are intended to remove some of the holes in the C type system introduced by the old C-style casts.

Lecture 20 C s Memory Model

Chapter 2. Procedural Programming

CS 11 C track: lecture 5

Outline. 1 Function calls and parameter passing. 2 Pointers, arrays, and references. 5 Declarations, scope, and lifetimes 6 I/O

CS201- Introduction to Programming Current Quizzes

CPSC 213. Introduction to Computer Systems. Winter Session 2017, Term 2. Unit 1c Jan 24, 26, 29, 31, and Feb 2

Common Misunderstandings from Exam 1 Material

Transcription:

Chapter 17 vector and Free Store Bjarne Stroustrup www.stroustrup.com/programming

Overview Vector revisited How are they implemented? Pointers and free store Allocation (new) Access Arrays and subscripting: [] Dereferencing: * Deallocation (delete) Destructors Copy constructor and copy assignment Arrays Array and pointer problems Changing size Templates Range checking and exceptions 4

Vector Vector is the most useful container Simple Compactly stores elements of a given type Efficient access Expands to hold any number of elements Optionally range-checked access How is that done? That is, how is vector implemented? We'll answer that gradually, feature after feature Vector is the default container prefer vector for storing elements unless there's a good reason not to 5

Building from the ground up The hardware provides memory and addresses Low level Untyped Fixed-sized chunks of memory No checking As fast as the hardware architects can make it The application builder needs something like a vector Higher-level operations Type checked Size varies (as we get more data) Run-time range checking Close-to optimally fast 6

Building from the ground up At the lowest level, close to the hardware, life s simple and brutal You have to program everything yourself You have no type checking to help you Run-time errors are found when data is corrupted or the program crashes We want to get to a higher level as quickly as we can To become productive and reliable To use a language fit for humans Chapter 17-19 basically shows all the steps needed The alternative to understanding is to believe in magic The techniques for building vector are the ones underlying all higher-level work with data structures 7

Vector A vector Can hold an arbitrary number of elements Up to whatever physical memory and the operating system can handle That number can vary over time E.g. by using push_back() Example vector<double> age(4); age[0]=.33; age[1]=22.0; age[2]=27.2; age[3]=54.2; age: 4 age[0]: age[1]: age[2]: age[3]: 0.33 22.0 27.2 54.2 8

Vector // a very simplified vector of doubles s (like vector<double>): class vector { int sz; // the number of elements ( the size ) double* elem; // pointer to the first element public: vector(int s); // constructor: allocate s elements, // let elem point to them // store s in sz int size() const { return sz; } // the current size }; * means pointer to so double* is a pointer to double What is a pointer? how do we make a pointer point to elements? How do we allocate elements? double 9

Pointer values Pointer values are memory addresses Think of them as a kind of integer values The first byte of memory is 0, the next 1, and so on A pointer p can hold the address of a memory location 0 1 2 p 600 2^20-1 600 7 A pointer points to an object of a given type E.g. a double* points to a double,, not to a string A pointer s type determines how the memory referred to by the pointer s value is used E.g. what a double* points to can be added not, say, concatenated 10

Vector (constructor) vector::vector(int s) // vector's constructor :sz(s), // store the size s in sz elem(new double[s]) // allocate s doubles s on the free store // store a pointer to those doubles s in elem { } // Note: new does not initialize elements (but the standard vector does) sz: 4 elem: A pointer Free store: new allocates memory from the free store and returns a pointer to the allocated memory 11

The computer s memory As a program sees it Local variables lives on the stack Global variables are static data The executable code are in the code section 12

The free store (sometimes called "the heap") You request memory "to be allocated" "on the free store" by the new operator The new operator returns a pointer to the allocated memory A pointer is the address of the first byte of the memory For example int* p = new int; // allocate one uninitialized int // int* means pointer to int int* q = new int[7]; // allocate seven uninitialized ints // an array of 7 ints double* pd = new double[n]; // allocate n uninitialized doubles A pointer points to an object of its specified type A pointer does not know how many elements it points to p: q: 13

Access p1: p2:??? 5 Individual elements int* p1 = new int; // get (allocate) a new uninitialized int int* p2 = new int(5); // get a new int initialized to 5 int x = *p2; // get/read the value pointed to by p2 // (or get the contents of what p2 points to ) // in this case, the integer 5 int y = *p1; // undefined: y gets an undefined value; don t do that 14

Access p3: 7 9 Arrays (sequences of elements) int* p3 = new int[5]; // get (allocate) 5 ints // array elements are numbered 0, 1, 2, p3[0] = 7; // write to ( set ) the 1 st element of p3 p3[1] = 9; int x2 = p3[1]; // get the value of the 2 nd element of p3 int x3 = *p3; // we can also use the dereference operator * for an array // *p3 means p3[0] (and vice versa) 15

Why use free store? To allocate objects that have to outlive the function that creates them: For example double* make(int n) // allocate n ints { } return new double[n]; Another example: vector's constructor 16

Pointer values Pointer values are memory addresses Think of them as a kind of integer values The first byte of memory is 0, the next 1, and so on 0 1 2 p2 *p2 2^20-1 7 // you can see pointer value (but you rarely need/want to): char* p1 = new char('c'); // allocate a char and initialize it to 'c' int* p2 = new int(7); // allocate an int and initialize it to 7 cout << "p1==" << p1 << " *p1==" << *p1 << "\n"; // p1==??? *p1==c cout << "p2==" << p2 << " *p2==" << *p2 << "\n"; // p2==??? *p2=7 17

Access A pointer does not know the number of elements that it's pointing to (only the address of the first element) double* p1 = new double; *p1 = 7.3; // ok p1: p1[0] = 8.2; // ok p1[17] = 9.4; // ouch! Undetected error p1[-4] = 2.4; // ouch! Another undetected error 8.2 7.3 double* p2 = new double[100]; p2: *p2 = 7.3; // ok p2[17] = 9.4; // ok p2[-4] = 2.4; // ouch! Undetected error 7.3 18

Access A pointer does not know the number of elements that it's pointing to double* p1 = new double; double* p2 = new double[100]; p1: p2: [0]: [99]: p1[17] = 9.4; // error (obviously) p1 = p2; // assign the value of p2 to p1 (after the assignment) p1: p1[17] = 9.4; // now ok: p1 now points to the array of 100 doubles 19

Access pi1: A pointer does know the type of the object that it's pointing to int* pi1 = new int(7); int* pi2 = pi1; // ok: pi2 points to the same object as pi1 double* pd = pi1; // error: can't assign an int* to a double* char* pc = pi1; // error: can't assign an int* to a char* There are no implicit conversions between a pointer to one value type to a pointer to another value type However, there are implicit conversions between value types: pc: *pc = 8; // ok: we can assign an int to a char *pc = *pi1; // ok: we can assign an int to a char 7 7 20

Pointers, arrays, and vector Note With pointers and arrays we are "touching" hardware directly with only the most minimal help from the language. Here is where serious programming errors can most easily be made, resulting in malfunctioning programs and obscure bugs Be careful and operate at this level only when you really need to vector is one way of getting almost all of the flexibility and performance of arrays with greater support from the language (read: fewer bugs and less debug time). 21

Vector (construction and primitive access) // a very simplified vector of doubles: class vector { int sz; // the size double* elem; // a pointer to the elements public: vector(int s) :sz(s), elem(new double[s]) { } // constructor double get(int n) const { return elem[n]; } // access: read void set(int n, double v) { elem[n]=v; } // access: write int size() const { return sz; } // the current size }; vector v(10); for (int i=0; i<v.size(); ++i) { v.set(i,i); cout << v.get(i) << ' '; } 10 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 22

A problem: memory leak double* calc(int result_size, int max) { double* p = new double[max];// allocate another max doubles // i.e., get max doubles s from the free store double* result = new double[result_size]; // use p to calculate results to be put in result return result; } double* r = calc(200,100); // oops! We forgot to give the memory // allocated for p back to the free store Lack of de-allocation (usually called "memory leaks") can be a serious problem in real-world programs A program that must run for a long time can't afford any memory leaks 23

A problem: memory leak double* calc(int result_size, int max) { int* p = new double[max]; // allocate another max doubles // i.e., get max doubles s from the free store double* result = new double[result_size]; // use p to calculate results to be put in result delete[ ] p; // de-allocate (free) that array // i.e., give the array back to the free store return result; } double* r = calc(200,100); // use r delete[ ] r; // easy to forget 24

Memory leaks A program that needs to run "forever" can't afford any memory leaks An operating system is an example of a program that runs forever If a function leaks 8 bytes every time it is called, how many days can it run before it has leaked/lost a megabyte? Trick question: not enough data to answer, but about 130,000 calls All memory is returned to the system at the end of the program If you run using an operating system (Windows, Unix, whatever) Program that runs to completion with predictable memory usage may leak without causing problems i.e., memory leaks aren t good/bad but they can be a major problem in specific circumstances 25

Memory leaks Another way to get a memory leak 1 st value p: void f() { double* p = new double[27]; // p = new double[42]; // delete[] p; } 2 nd value // 1 st array (of 27 doubles) leaked 26

Memory leaks How do we systematically and simply avoid memory leaks? don't mess directly with new and delete Use vector,, etc. Or use a garbage collector A garbage collector is a program the keeps track of all of your allocations and returns unused free-store allocated memory to the free store (not covered in this course; see http://www.research.att.com/~bs/c++.html) Unfortunately, even a garbage collector doesn t prevent all leaks See also Chapter 25 27

A problem: memory leak void f(int x) { vector v(x); // define a vector // (which allocates x doubles s on the free store) // use v } // give the memory allocated by v back to the free store // but how? (vector( vector's elem data member is private) 28

Vector (destructor) // a very simplified vector of doubles: class vector { int sz; // the size double* elem; // a pointer to the elements public: vector(int s) // constructor: allocates/acquires memory :sz(s), elem(new double[s]) { } ~vector() // destructor: de-allocates/releases memory { delete[ ] elem; } // }; Note: this is an example of a general and important technique: acquire resources in a constructor release them in the destructor Examples of resources: memory, files, locks, threads, sockets 29

A problem: memory leak void f(int x) { } int* p = new int[x]; // allocate x ints vector v(x); // define a vector (which allocates another x ints) // use p and v delete[ ] p; // deallocate the array pointed to by p // the memory allocated by v is implicitly deleted here by vector's destructor The delete now looks verbose and ugly How do we avoid forgetting to delete[ ] p? p Experience shows that we often forget Prefer deletes s in destructors 30

Free store summary Allocate using new New allocates an object on the free store, sometimes initializes it, and returns a pointer to it int* pi = new int; // default initialization (none for int) char* pc = new char('a'); // explicit initialization double* pd = new double[10]; // allocation of (uninitialized) array New throws a bad_alloc exception if it can't allocate Deallocate using delete and delete[ ] delete and delete[ ] return the memory of an object allocated by new to the free store so that the free store can use it for new allocations delete pi; // deallocate an individual object delete pc; // deallocate an individual object delete[ ] pd; // deallocate an array Delete of a zero-valued pointer ("the null pointer") does nothing char* p = 0; delete p; // harmless 31

void* void* means pointer to some memory that the compiler doesn't know the type of We use void* when we want to transmit an address between pieces of code that really don't know each other's types so the programmer has to know Example: the arguments of a callback function There are no objects of type void void v; // error void f(); // f() returns nothing f() does not return an object of type void Any pointer to object can be assigned to a void* int* pi = new int; double* pd = new double[10]; void* pv1 = pi; void* pv2 = pd; 32

void* To use a void* we must tell the compiler what it points to void f(void* pv) { void* pv2 = pv; // copying is ok (copying is what void*s are for) double* pd = pv; // error: can t implicitly convert void* to double* *pv = 7; // error: you can t dereference a void* // good! The int 7 is not represented like the double 7.0) pv[2] = 9; // error: you can t subscript a void* pv++; // error: you can t increment a void* int* pi = static_cast<int*>(pv); // ok: explicit conversion // } A static_cast can be used to explicitly convert to a pointer to object type "static_cast"" is a deliberately ugly name for an ugly (and dangerous) operation use it only when absolutely necessary 33

void* void* is the closest C++ has to a plain machine address Some system facilities require a void* Remember FLTK callbacks? Address is a void*: typedef void* Address; void Lines_window::cb_next(Address,Address) Avoid using it if you possibly can (nmm) It bypasses essentially all type checks 34

Pointers and references Think of a reference as an automatically dereferenced pointer Or as an alternative name for an object A reference must be initialized The value of a reference cannot be changed after initialization int x = 7; int y = 8; int* p = &x; *p = 9; p = &y; // ok int& r = x; x = 10; r = &y; // error (and so is all other attempts to change what r refers to) 35

Function results etc. (nmm) Be careful when returning references and pointers from functions The object referred to is not copied, so mustn't go away or be replaced when the function returns There are some arcane restrictions on references to stop some errors of that form The precise rules are extremely complicated, and you don't need to know them Try to understand why the book uses them the way it does, because that is a correct and safe use 36

Compiler Checks (nmm) Using raw pointers, void* etc. is like using assembler You are saying don't do any checking I don't make mistakes Well, you will I do, often and I have been a programmer since 1966, including lots of assembler In particular, NO compiler can check the following: When your pointer value is invalid (e.g. uninitialised) Bounds (size) errors when using raw (C-style) pointers Type errors when using void* And any errors will cause CHAOS They don't check that a pointer is not null, though they could Some library classes will, but that's about all 37

Warnings (nmm) The description of memory layout is an example It describes an over-simplified Unix layout, and current systems are much more complicated Never write programs that assume any particular layout Even the stack may grow both up and down! You can run out of a type of memory (stack, heap or other) long before you run out of memory The simplest solution is to compile for 64-bit addressing 32-bit desktop systems have been obsolete for over 5 years That has NOTHING to do with how much memory they have Generally, use a 64-bit system if you have 1 GB of memory or more 38

Warnings (nmm) There are some serious gotchas when using casts on pointers, so try to avoid them They are far too complicated to cover in this course There is precisely one safe use, to get back to the type you started with and a compiler can't check you got it right myclass object(); myclass * myptr = object.addr(); void * rawptr = myptr;... myclass * newptr = static_cast<myclass *>(rawptr); 39

Don't Write C (nmm) You will often see C-style casts in C++ code derived from C or by C programmers writing C++ They look like (newtype)expression But don't write them They are extremely hard to spot in non-trivial code They are even less safe than reinterpret_cast 40

Exercises (nmm) In the drills The word allocate implies use operator new In the first part, point 2, you won't always get zero; the problem is that you usually do In the second part, use the variables p? for everything (including deallocation) after the initial allocation and initialisation In the second part, point 7, assign p3 to p1 41

Exercises (nmm) In exercise 3, letters means A-Z (and a-z) only Don't assume that 'Z' == 'A'+25 (it need not be) In exercise 13, 'move' means that you should copy the element, and then delete it 42

Next lecture The next lecture discusses copying and arrays 43