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

Similar documents
Pointers, Dynamic Data, and Reference Types

C: Pointers, Arrays, and strings. Department of Computer Science College of Engineering Boise State University. August 25, /36

CS201- Introduction to Programming Current Quizzes

Type Aliases. Examples: using newtype = existingtype; // C++11 typedef existingtype newtype; // equivalent, still works

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

Memory, Arrays & Pointers

Vector and Free Store (Vectors and Arrays)

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

Chapter 17 vector and Free Store

Chapter 17 vector and Free Store

Pointers and Memory 1

calling a function - function-name(argument list); y = square ( z ); include parentheses even if parameter list is empty!

C++ for Java Programmers

C-String Library Functions

Chapter 13: Copy Control. Overview. Overview. Overview

Vector and Free Store (Pointers and Memory Allocation)

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

SYSC 2006 C Winter String Processing in C. D.L. Bailey, Systems and Computer Engineering, Carleton University

[0569] p 0318 garbage

Pointers and Arrays CS 201. This slide set covers pointers and arrays in C++. You should read Chapter 8 from your Deitel & Deitel book.

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

Chapter 17 vector and Free Store. Bjarne Stroustrup

Arrays. Returning arrays Pointers Dynamic arrays Smart pointers Vectors


For example, let s say we define an array of char of size six:

C: Arrays, and strings. Department of Computer Science College of Engineering Boise State University. September 11, /16

nptr = new int; // assigns valid address_of_int value to nptr std::cin >> n; // assigns valid int value to n

A brief introduction to C programming for Java programmers

ECE 15B COMPUTER ORGANIZATION

Dynamic Allocation in C

CS106L Handout #05 Fall 2007 October 3, C Strings

CSCI 6610: Intermediate Programming / C Chapter 12 Strings

CS162 - POINTERS. Lecture: Pointers and Dynamic Memory

FORM 1 (Please put your name and section number (001/10am or 002/2pm) on the scantron!!!!) CS 161 Exam II: True (A)/False(B) (2 pts each):


Pointers and References

Administrivia. Introduction to Computer Systems. Pointers, cont. Pointer example, again POINTERS. Project 2 posted, due October 6

Arrays array array length fixed array fixed length array fixed size array Array elements and subscripting

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

void setup(){ void loop() { The above setup works, however the function is limited in the fact it can not be reused easily. To make the code more gene

To declare an array in C, a programmer specifies the type of the elements and the number of elements required by an array as follows

Ch. 12: Operator Overloading

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

I2204 ImperativeProgramming Semester: 1 Academic Year: 2018/2019 Credits: 5 Dr Antoun Yaacoub

Object Oriented Programming COP3330 / CGS5409

Review of the C Programming Language for Principles of Operating Systems

CSCI 262 Data Structures. Arrays and Pointers. Arrays. Arrays and Pointers 2/6/2018 POINTER ARITHMETIC

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

C-LANGUAGE CURRICULAM

C++ for Java Programmers

Homework #3 CS2255 Fall 2012

CSC209H Lecture 4. Dan Zingaro. January 28, 2015

Dynamic Allocation in C

Pointers and Memory Management

Chapter 8 Arrays and Strings. Objectives. Objectives (cont d.) Introduction. Arrays 12/23/2016. In this chapter, you will:

Jagannath Institute of Management Sciences Lajpat Nagar. BCA II Sem. C Programming

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

C: Pointers. C: Pointers. Department of Computer Science College of Engineering Boise State University. September 11, /21

Agenda. Peer Instruction Question 1. Peer Instruction Answer 1. Peer Instruction Question 2 6/22/2011

12. Pointers Address-of operator (&)

CS201 Latest Solved MCQs

6. User Defined Functions I

Before we start - Announcements: There will be a LAB TONIGHT from 5:30 6:30 in CAMP 172. In compensation, no class on Friday, Jan. 31.

by Pearson Education, Inc. All Rights Reserved.

ALL ABOUT POINTERS C/C++ POINTERS

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

What is Pointer? Pointer is a variable that holds a memory address, usually location of another variable.

CSI33 Data Structures

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

WHAT POINTERS REALLY ARE

Review of the C Programming Language

1 Pointer Concepts. 1.1 Pointer Examples

CS 61c: Great Ideas in Computer Architecture

QUIZ. What is wrong with this code that uses default arguments?

Computer Programming: Skills & Concepts (CP) Strings

Arrays and Memory Management

Chapter 10 Pointers and Dynamic Arrays. GEDB030 Computer Programming for Engineers Fall 2017 Euiseong Seo

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

Reading Assignment. Strings. K.N. King Chapter 13. K.N. King Sections 23.4, Supplementary reading. Harbison & Steele Chapter 12, 13, 14

Programming. Pointers, Multi-dimensional Arrays and Memory Management

1 Lexical Considerations

Chapter 5 - Pointers and Strings

CS 61C: Great Ideas in Computer Architecture. Lecture 3: Pointers. Bernhard Boser & Randy Katz

Chapter 5 - Pointers and Strings

Quiz Start Time: 09:34 PM Time Left 82 sec(s)

Chapter 10. Pointers and Dynamic Arrays. Copyright 2016 Pearson, Inc. All rights reserved.

KOM3191 Object Oriented Programming Dr Muharrem Mercimek ARRAYS ~ VECTORS. KOM3191 Object-Oriented Computer Programming

Agenda. Components of a Computer. Computer Memory Type Name Addr Value. Pointer Type. Pointers. CS 61C: Great Ideas in Computer Architecture

Short Notes of CS201

CS201 Some Important Definitions

Pointers. Reference operator (&) ted = &andy;

CSC 211 Intermediate Programming. Arrays & Pointers

CS 61C: Great Ideas in Computer Architecture. Lecture 3: Pointers. Krste Asanović & Randy Katz

ONE DIMENSIONAL ARRAYS

CS201 - Introduction to Programming Glossary By

Dynamic Allocation of Memory

Lecture 14. No in-class files today. Homework 7 (due on Wednesday) and Project 3 (due in 10 days) posted. Questions?

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

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

Model Viva Questions for Programming in C lab

Transcription:

Arrays and Pointers Arrays Introducing Pointers C-Style Character Strings Multidimensioned Arrays 1 Overview C++ defines two lower-level compound types: arrays and pointers that are similar to vectors and iterators an array holds a collection of objects of same type unlike vectors, arrays are fixed size; once an array is created, new elements cannot be added like iterators, pointers can be used to navigate among and examine the elements in an array 2 1

Overview modern C++ programs should almost always use vectors and iterators in preference to the lowerlevel arrays and pointers well-designed programs use arrays and pointers only in the internals of class implementations where speed is essential 3 Arrays an array is a container of objects of a single data type individual objects are not named; rather, each one is accessed by its position in the array drawbacks compared to vectors: they are fixed size, and they offer no help to the programmer in keeping track of how big a given array is there is no push_back to automatically add elements if the array size needs to change, then the programmer must allocate a new, larger array and copy the elements into that new space. 4 2

Arrays An array is a compound type that consists of a type specifier, an identifier, and a dimension type specifier indicates what type the elements stored in the array // both buf_size and max_files are const const unsigned buf_size = 512, max_files = 20; int staff_size = 27; // nonconst const unsigned sz = get_size(); // const value not known until run time char input_buffer[buf_size]; // ok: const variable string filetable[max_files + 1]; // ok: constant expression double salaries[staff_size]; // error: non const variable int test_scores[get_size()]; // error: non const expression int vals[sz]; // error: size not known until run time 5 Initializing Array Elements const unsigned array_size = 3; int ia[array_size] = {0, 1, 2}; int ia[] = {0, 1, 2}; // an array of dimension 3 const unsigned array_size = 5; // Equivalent to ia = {0, 1, 2, 0, 0} // ia[3] and ia[4] default initialized to 0 int ia[array_size] = {0, 1, 2}; // Equivalent to str_arr = {"hi", "bye", "", "", ""} // str_arr[2] through str_arr[4] default initialized to the empty string string str_arr[array_size] = {"hi", "bye"}; 6 3

Character Arrays Are Special a character array can be initialized with either a list of comma-separated character literals enclosed in braces or a string literal char ca1[] = {'C', '+', '+'}; // no null char ca2[] = {'C', '+', '+', '\0'}; // explicit null char ca3[] = "C++"; // null terminator added automatically const char ch3[6] = "Daniel"; // error: Daniel is 7 elements 7 No Array Copy or Assignment unlike a vector, it is not possible to initialize an array as a copy of another array nor is it legal to assign one array to another int ia[] = {0, 1, 2}; // ok: array of ints int ia2[](ia); // error: cannot initialize one array with another int main() { const unsigned array_size = 3; int ia3[array_size]; // ok: but elements are uninitialized! } ia3 = ia; return 0; // error: cannot assign one array to another 8 4

Operations on Arrays array elements are numbered beginning with 0, and may be accessed using the subscript operator we subscript a vector, we use vector::size_type as the type for the index. When we subscript an array, the right type to use for the index is size_t int main() { const size_t array_size = 7; int ia1[] = { 0, 1, 2, 3, 4, 5, 6 }; int ia2[array_size]; // local array, elements uninitialized // copy elements from ia1 into ia2 for (size_t ix = 0; ix!= array_size; ++ix) ia2[ix] = ia1[ix]; return 0; } 9 Checking Subscript Values the programmer must guarantee that the subscript value is in range the most common causes of security problems are so-called "buffer overflow" bugs these bugs occur when a subscript is not checked and reference is made to an element outside the bounds of an array or other similar data structure 10 5

Introducing Pointers a pointer is a compound type, pointing to an object of some other type pointers are iterators for arrays: A pointer can point to an element in an array when we dereference a pointer, we obtain the object to which the pointer points when we increment a pointer, we advance the pointer to denote the next element in the array 11 What Is a Pointer? pointers are often hard to understand, even for experienced programmers pointers are an important part of most C programs and to a much lesser extent remain important in many C++ programs Specifically, a pointer holds the address of another object string s("hello world"); string *sp = &s; // sp holds the address of s 12 6

Advice: Avoid Pointers and Arrays Pointers and arrays are surprisingly error-prone many useful programs can be written without needing to use arrays or pointers modern C++ programs use vectors and iterators to replace general arrays and strings to replace C-style array-based character strings. 13 Defining and Initializing Pointers every pointer has an associated type, we use the * symbol in a declaration to indicate that an identifier is a pointer vector<int> *pvec; // pvec can point to a vector<int> int *ip1, *ip2; // ip1 and ip2 can point to an int string *pstring; // pstring can point to a string double *dp; // dp can point to a double int ival = 1024; int *pi = 0; // pi initialized to address no object int *pi2 = & ival; // pi2 initialized to address of ival int *pi3; // ok, but dangerous, pi3 is uninitialized pi = pi2; // pi and pi2 address the same object, e.g. ival pi2 = 0; // pi2 now addresses no object 14 7

Avoid Uninitialized Pointers uninitialized pointers are a common source of runtime errors using an uninitialized pointer almost always results in a run-time crash however, the fact that the crash results from using an uninitialized pointer can be quite hard to track down if possible, do not define a pointer until the object to which it should point has been defined. That way, there is no need to define an uninitialized pointer 15 Constraints on Initialization of and Assignment to Pointers There are only four kinds of values that may be used to initialize or assign to a pointer: A constant expression with value 0 (e.g., a const integral object whose value is zero at compile time or a literal constant 0) An address of an object of an appropriate type The address one past the end of another object Another valid pointer of the same type int ival; int zero = 0; const int c_ival = 0; int *pi = ival; // error: pi initialized from int value of ival pi = zero; // error: pi assigned int value of zero pi = c_ival; // ok: c_ival is a const with compile-time value of 0 16 pi = 0; // ok: directly initialize to literal constant 0 8

Constraints on Initialization of and Assignment to Pointers // cstdlib #defines NULL to 0 int *pi = NULL; // ok: equivalent to int *pi = 0; double dval; double *pd = &dval; // ok: initializer is address of a double double *pd2 = pd; // ok: initializer is a pointer to double int *pi = pd; // error: types of pi and pd differ pi = &dval; // error: attempt to assign address of a double to int * 17 void* Pointers void* is a special pointer type that can hold an address of any object a void* indicates that the associated value is an address but that the type of the address is unknown. There are only a limited number of actions we can perform on a void* pointer: compare it to another pointer pass or return it from a function assign it to another void* pointer cannot use the pointer to operate on the object it addresses. 18 9

void* Pointers double obj = 3.14; double *pd = &obj; // ok: void* can hold the address value of any data pointer type void *pv = &obj; // obj can be an object of any type pv = pd; // pd can be a pointer to any type 19 Operations on Pointers Pointers allow indirect manipulation of the object to which the pointer points We can access the object by dereferencing the pointer. Dereferencing a pointer is similar to dereferencing an iterator The * operator (the dereference operator) returns the object to which the pointer points: string s("hello world"); string *sp = &s; // sp holds the address of s cout <<*sp; // prints hello world 20 10

Operations on Pointers 1 Legal? (a) string s, *sp = 0; (b) int i; double* dp = &i; (c) int* ip, ip2; (d) const int i = 0, *p = i; (e) string *p = NULL; 2 Given a pointer, p, can you determine whether p points to a valid object? If so, how? If not, why not? 3 Why is the first pointer initialization legal and the second illegal? int i = 42; void *p = &i; long *lp = &i; 21 Dereference the dereference operator returns the lvalue of the underlying object so we can use it to change the value of the object to which the pointer points *sp = "goodbye"; // contents of s now changed string s2 = "some value"; sp = &s2; // sp now points to s2 22 11

Key Concept: Assigning TO or THROUGH a Pointer the difference in whether an assignment is to the pointer or through the pointer to the value pointed to can be confusing important thing to keep in mind is that if the lefthand operand is dereferenced, then the value pointed to is changed if there is no dereference, then the pointer itself is being changed 23 Key Concept: Assigning TO or THROUGH a Pointer 24 12

Comparing Pointers and References While both references and pointers are used to indirectly access another value, there are two important differences between the two: a reference always refers to an object: It is an error to define a reference without initializing it. assigning to a reference changes the object to which the reference is bound; it does not rebind the reference to another object. Once initialized, a reference always refers to the same underlying object. int ival = 1024, ival2 = 2048; int *pi = &ival, *pi2 = &ival2; pi = pi2; // pi now points to ival2 int &ri = ival, &ri2 = ival2; ri = ri2; // assigns ival2 to ival 25 Comparing Pointers and References While both references and pointers are used to indirectly access another value, there are two important differences between the two: a reference always refers to an object: It is an error to define a reference without initializing it. assigning to a reference changes the object to which the reference is bound; it does not rebind the reference to another object. Once initialized, a reference always refers to the same underlying object. int ival = 1024, ival2 = 2048; int *pi = &ival, *pi2 = &ival2; pi = pi2; // pi now points to ival2 int &ri = ival, &ri2 = ival2; ri = ri2; // assigns ival2 to ival 26 13

Pointers to Pointers Pointers are themselves objects in memory. They, therefore, have addresses that we can store in a pointer int ival = 1024; int *pi = &ival; // pi points to an int int **ppi = π // ppi points to a pointer to int int *pi2 = *ppi; // ppi points to a pointer To actually access ival, we need to dereference ppi twice: cout << "The value of ival\n" << "direct value: " << ival << "\n" << "indirect value: " << *pi << "\n" << "doubly indirect value: " << **ppi << endl; 27 Pointers to Pointers: Exercise What does the following program do? int i = 42, j = 1024; int *p1 = &i, *p2 = &j; *p2 = *p1 * *p2; *p1 *= *p1; 28 14

Using Pointers to Access Array Elements pointers and arrays are closely intertwined in C++ when we use the name of an array in an expression, that name is automatically converted into a pointer to the first element of the array int ia[] = {0,2,4,6,8}; int *ip = ia; // ip points to ia[0] If we want to point to another element in the array, we could do so by using the subscript operator to locate the element and then applying the address-of operator to find its location ip = &ia[4]; // ip points to last element in ia 29 Pointer Arithmetic Rather than taking the address of the value returned by subscripting, we could use pointer arithmetic Pointer arithmetic works the same way (and has the same constraints) as iterator arithmetic Using pointer arithmetic, we can compute a pointer to an element by adding (or subtracting) an integral value to (or from) a pointer to another element in the array ip = ia; // ok: ip points to ia[0] int *ip2 = ip + 4; // ok: ip2 points to ia[4], the last element in ia ptrdiff_t n = ip2 - ip; // ok: distance between the pointers 30 15

Subscripts and Pointers when we subscript an array, we are really subscripting a pointer ip = ia; // ok: ip points to ia[0] int *ip2 = ip + 4; // ok: ip2 points to ia[4], the last element in ia int ia[] = {0,2,4,6,8}; int i = ia[0]; // ia points to the first element in ia int *p = &ia[2]; // ok: p points to the element indexed by 2 int j = p[1]; // ok: p[1] equivalent to *(p + 1), // p[1] is the same element as ia[3] int k = p[-2]; // ok: p[-2] is the same element as ia[0] 31 Printing the Elements of an Array when we subscript an array, we are really subscripting a pointer const size_t arr_sz = 5; int int_arr[arr_sz] = { 0, 1, 2, 3, 4 }; // pbegin points to first element, pend points just after the last for (int *pbegin = int_arr, *pend = int_arr + arr_sz; pbegin!= pend; ++pbegin) cout << *pbegin << ' '; // print the current element 32 16

Pointers Are Iterators for Arrays the built-in array type has many of the properties of a library container pointers, when we use them in conjunction with arrays, are themselves iterators 33 Pointers to const Objects the language requires that pointers to const objects must take the constness of their target into account const double *cptr; // cptr may point to a double that is const It is also a compile-time error to assign the address of a const object to a plain, nonconst pointer *cptr = 42; // error: *cptr might be const It is also a compile-time error to assign the address of a const object to a plain, nonconst pointer const double pi = 3.14; double *ptr = π // error: ptr is a plain pointer const double *cptr = π // ok: cptr is a pointer to const 34 17

Pointers to const Objects cannot use a void* pointer to hold the address of a const object. Instead, we must use the type const void* to hold the address of a const object const int universe = 42; const void *cpv = &universe; // ok: cpv is const void *pv = &universe; // error: universe is const A pointer to a const object can be assigned the address of a nonconst object double dval = 3.14; // dval is a double; its value can be changed cptr = &dval; // ok: but can't change dval through cptr 35 Pointers to const Objects dval = 3.14159; // dval is not const *cptr = 3.14159; // error: cptr is a pointer to const double *ptr = &dval; // ok: ptr points at non-const double *ptr = 2.72; // ok: ptr is plain pointer cout << *cptr; // ok: prints 2.72 36 18

C-style character strings a string literal is an array of const char C-style strings are null-terminated arrays of characters char ca1[] = {'C', '+', '+'}; // no null, not C-style string char ca2[] = {'C', '+', '+', '\0'}; // explicit null char ca3[] = "C++"; // null terminator added automatically const char *cp = "C++"; // null terminator added automatically char *cp1 = ca1; // points to first element of a array, but not C-style string char *cp2 = ca2; // points to first element of a null-terminated char array 37 Using C-style Strings C-style strings are manipulated through (const) char* pointers One frequent usage pattern uses pointer arithmetic to traverse the C-style string. The traversal tests and increments the pointer until we reach the terminating null character const char *cp = "some value"; while (*cp) { // do something to *cp ++cp; } 38 19

C Library String Functions strlen(s) Returns the length of s, not counting the null. strcmp(s1, s2) Compares s1 and s2 for equality. Returns 0 if s1 == s2, positive value if s1 > s2, negative value if s1 < s2. strcat(s1, s2) Appends s2 to s1. Returns s1. strcpy(s1, s2) Copies s2 into s1. Returns s1. strncat(s1, s2,n) Appends n characters from s2 onto s1. Returns s1. strncpy(s1, s2, n) Copies n characters from s2 into s1. Returns s1. 39 C Library String Functions const char *cp1 = "A string example"; const char *cp2 = "A different string"; int i = strcmp(cp1, cp2); // i is positive i = strcmp(cp2, cp1); // i is negative i = strcmp(cp1, cp1); // i is zero 40 20

Never Forget About the Null- Terminator When using the C library string functions it is essential to remember the strings must be nullterminated char ca[] = {'C', '+', '+'}; // not null-terminated cout << strlen(ca) << endl; // disaster: ca isn't null-terminated 41 Caller Is Responsible for Size of a Destination String The array that we pass as the first argument to strcat and strcpy must be large enough to hold the generated string // Dangerous: What happens if we miscalculate the size of largestr? char largestr[16 + 18 + 2]; // will hold cp1 a space and cp2 strcpy(largestr, cp1); // copies cp1 into largestr strcat(largestr, " "); // adds a space at end of largestr strcat(largestr, cp2); // concatenates cp2 to largestr // prints A string example A different string cout << largestr << endl; 42 21

Caller Is Responsible for Size of a Destination String it is usually safer to use the strncat and strncpy functions instead of strcat and strcpy properly calculate the value to control how many characters get copied always remember to account for the null when copying or concatenating characters char largestr[16 + 18 + 2]; // to hold cp1 a space and cp2 strncpy(largestr, cp1, 17); // size to copy includes the null strncat(largestr, " ", 2); // pedantic, but a good habit strncat(largestr, cp2, 19); // adds at most 18 characters, plus a null 43 Whenever Possible, Use Library strings library handles all memory management, and we need no longer worry if the size of either string changes string largestr = cp1; // initialize large Str as a copy of cp1 largestr += " "; // add space at end of largestr largestr += cp2; // concatenate cp2 onto end of largestr 44 22

Dynamically Allocating Arrays array type has three important limitations: its size is fixed the size must be known at compile time array exists only until the end of the block in which it was defined need a way to allocate an array dynamically at run time the size of a dynamically allocated array need not be fixed at compile time it can be (and usually is) determined at run time unlike an array variable, a dynamically allocated array continues to exist until it is explicitly freed by the program 45 Dynamically Allocating Arrays every program has a pool of available memory it can use during program execution to hold dynamically allocated objects this pool of available memory is referred to as the program's free store or heap C programs use a pair of functions named malloc and free to allocate space from the free store in C++ we use new and delete expressions. What does the following program do? const char ca[] = {'h', 'e', 'l', 'l', 'o'}; const char *cp = ca; while (*cp) { cout << *cp << endl; ++cp; } 46 23

Defining a Dynamic Array specify the type and size but do not name the object the new expression returns a pointer to the first element in the newly allocated array int *pia = new int[10]; // array of 10 uninitialized ints 47 Initializing a Dynamically Allocated Array when we allocate an array of objects of a class type, then that type's default constructor is used to initialize each element if the array holds elements of built-in type, then the elements are uninitialized string *psa = new string[10]; // array of 10 empty strings int *pia = new int[10]; // array of 10 uninitialized ints 48 24

Initializing a Dynamically Allocated Array we can value-initialize the elements by following the array size by an empty pair of parentheses string *psa = new string[10]; // array of 10 empty strings int *pia = new int[10]; // array of 10 uninitialized ints parentheses are effectively a request to the compiler to valueinitialize the array, which in this case sets its elements to 0 int *pia2 = new int[10] (); 49 Legal to Dynamically Allocate an Empty Array When we dynamically allocate an array, we often do so because we don't know the size of the array at compile time size_t n = get_size(); // returns number of elements needed int* p = new int[n]; for (int* q = p; q!= p + n; ++q) /* process the array */ ; 50 25

Legal to Dynamically Allocate an Empty Array It is legal even though we could not create an array variable of size 0 char arr[0]; // error: cannot define zero-length array char *cp = new char[0]; // ok: but cp can't be dereferenced new returns a valid, nonzero pointer this pointer will be distinct from any other pointer returned by new. The pointer cannot be dereferencedafter all, it points to no element 51 Freeing Dynamic Memory When we allocate memory, we must eventually free it. Otherwise, memory is gradually used up When we no longer need the array, we must explicitly return its memory to the free store We do so by applying the delete [] expression to a pointer that addresses the array we want to release delete [] pia; deallocates the array pointed to by pia, returning the associated memory to the free store the empty bracket pair between the delete keyword and the pointer is necessary: It indicates to the compiler that the pointer addresses an array of elements on the free store and not simply a single object 52 26

Contrasting C-Style Strings and C++ Library strings The string version is shorter, easier to understand, and less error-prone // C-style character string implementation const char *pc = "a very long literal string"; const size_t len = strlen(pc +1); // space to allocate // performance test on string allocation and copy for (size_t ix = 0; ix!= 1000000; ++ix) { char *pc2 = new char[len + 1]; // allocate the space strcpy(pc2, pc); // do the copy if (strcmp(pc2, pc)) // use the new string ; // do nothing delete [] pc2; // free the memory } 53 Contrasting C-Style Strings and C++ Library strings The string version is shorter, easier to understand, and less error-prone // string implementation string str("a very long literal string"); // performance test on string allocation and copy for (int ix = 0; ix!= 1000000; ++ix) { string str2 = str; // automatically allocated if (str!= str2) // use the new string ; // do nothing } // str2 is automatically freed 54 27

Multidimensioned Arrays multidimensioned array is actually an array of arrays // array of size 3, each element is an array of ints of size 4 int ia[3][4]; int ia[3][4] = {/* 3 elements, each element is array of size 4 */ {0, 1, 2, 3}, /* initializers for row indexed by 0 */ {4, 5, 6, 7}, /* initializers for row indexed by 1 */ {8, 9, 10, 11} /* initializers for row indexed by 2 */ }; // equivalent without the optional nested braces for each row int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11}; 55 Multidimensioned Arrays multidimensioned array is actually an array of arrays // explicitly initialize only element 0 in each row int ia[3][4] = {{ 0 }, { 4 }, { 8 } }; If the nested braces were omitted, the results would be very different: // explicitly initialize row 0 int ia[3][4] = {0, 3, 6, 9}; 56 28

Subscripting Multidimensioned Array const size_t rowsize = 3; const size_t colsize = 4; int ia [rowsize][colsize]; // 12 uninitialized elements // for each row for (size_t i = 0; i!= rowsize; ++i) // for each column within the row for (size_t j = 0; j!= colsize; ++j) // initialize to its positional index ia[i][j] = i * colsize + j; 57 Subscripting Multidimensioned Array if an expression provides only a single index, then the result is the inner-array element at that row index. ia[2] fetches the array that is the last row in ia. It does not fetch any element from that array; it fetches the array itself. 58 29

Pointers and Multidimensioned Arrays when we use the name of a multidimensioned array, it is automatically converted to a pointer to the first element in the array when defining a pointer to a multidimensioned array, it is essential to remember that what we refer to as a multidimensioned array is really an array of arrays because a multidimensioned array is really an array of arrays, the pointer type to which the array converts is a pointer to the first inner array. 59 Pointers and Multidimensioned Arrays although conceptually straightforward, the syntax for declaring such a pointer can be confusing: int ia[3][4]; // array of size 3, each element is an array of // ints of size 4 int (*ip)[4] = ia; // ip points to an array of 4 ints ip = &ia[2]; // ia[2] is an array of 4 ints 60 30

Pointers and Multidimensioned Arrays we define a pointer to an array similarly to how we would define the array itself: start by declaring the element type followed by a name and a dimension the name is a pointer, so we must prepend * to the name. read the definition of ip from the inside out as saying that *ip has type int[4] that is, ip is a pointer to an int array of four elements int ia[3][4]; // array of size 3, each element is an array of // ints of size 4 int (*ip)[4] = ia; // ip points to an array of 4 ints ip = &ia[2]; // ia[2] is an array of 4 ints 61 Pointers and Multidimensioned Arrays The parentheses in this declaration are essential: int *ip[4]; // array of pointers to int int (*ip)[4]; // pointer to an array of 4 ints 62 31

Typedefs Simplify Pointers to Multidimensioned Arrays typedef int int_array[4]; int_array *ip = ia; for (int_array *p = ia; p!= ia + 3; ++p) for (int *q = *p; q!= *p + 4; ++q) cout << *q << endl; 63 32