dynamic memory allocation in c++

Post on 03-Feb-2022

21 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Dynamic Memory Allocation in C++

An Introduction

Prof. David Bernstein

James Madison University

Computer Science Department

bernstdh@jmu.edu

Motivation An Observation:

o We often don't know how much space we will need to store things at "compile time"

o Dynamic memory allocation is the allocation of memory at "run time"

Past Experience:

o You've seen some of this before in Java, since all objects use memory that is allocated at "run time"

Diferences between Static and Dynamic Memory Allocation Dynamically allocated memory is kept on the memory heap (also known as

the free store)

Dynamically allocated memory can't have a "name" it must be referred to

Declarations are used to statically allocate memory, the new operator is used to

dynamically allocate memory

Pointing to Memory Allocated at Run Time An Example:

o

o int *ptr;

o

Illustration:

o

Pointing to Memory Allocated at Run Time (cont.) An Example:

o

o ptr = new int;

o

Illustration:

o

Using Memory Allocated at Run Time An Example:

o

o *ptr = 7;

o

Illustration:

o

Run Time Allocation of Arrays An Example:

o

o int *a;

o

Illustration:

o

Run Time Allocation of Arrays (cont.) An Example:

o

o a = new int[3];

o

Illustration:

o

Run Time Allocation of Arrays (cont.)

An Example:

o

o *a = 300;

o *(a+1) = 301;

o *(a+2) = 302;

o

Illustration:

o

Run Time Allocation of Arrays (cont.) An Observation:

o *a and a[0] are syntactically different ways to refer to the same value

An Explanation:

o The [] operator performs pointer arithemtic and de-references the resulting pointer.

Returning Memory to the Heap How Big is the Heap?

o It can only contain as much physical memory as you have installed or as much virtual memory as your operating system can make available (if it supports virtual memory)

Running Out of Memory:

o Most applications request memory from the heap when they are running

o It is possible to run out of memory (you may even have gotten a message like "Running Low On Virtual Memory")

o So, it is important to return memory to the heap when you no longer need it

Returning Memory to the Heap (cont.) The Opposite of new:

o In C++: The delete operator in C++

o In Java: The JVM has a garbage collector that returns unused memory

An Example:

o

o delete ptr;

o

Illustration:

o

Returning Memory to the Heap (cont.) Dangling Pointers:

o The delete operator does not delete the pointer, it takes the memory being pointed to

and returns it to the heap

o It does not even change the contents of the pointer

o Since the memory being pointed to is no longer available (and may even be given to another application), such a pointer is said to be dangling

An Example:

o

o ptr = NULL;

o

Illustration:

o

Returning Memory to the Heap (cont.) Remember:

o Return memory to the heap before undangling the pointer

What's Wrong with the Following:

o

o ptr = NULL;

o

o delete ptr;

o

Returning Memory to the Heap (cont.) What About Arrays?

o You want to return all of the memory to the heap

o So, a different form of the delete operator is needed

o Also, the memory allocator must keep track of the size of the array

An Example:

o

o delete[] a;

o

Illustration:

o

Returning Memory to the Heap (cont.) An Example:

o

o a = NULL;

o

Illustration:

o

Memory Leaks An Explanation:

o Memory leaks when it is allocated from the heap using the new operator but not

returned to the heap using the delete operator

An Example:

o

o int *otherptr;

o

Illustration:

o

Memory Leaks (cont.) An Example:

o

o otherptr = new int;

o

Illustration:

o

Memory Leaks (cont.) An Example:

o

o *otherptr = 4;

o

Illustration:

o

Memory Leaks (cont.)

An Example:

o

o otherptr = new int;

o

Illustration:

o

Memory Leaks (cont.) An Example:

o

o *otherptr = 5;

o

Illustration:

o

Dynamic Allocation of Objects A Simple Class to Get Us Started

cppexamples\memory\Weight.h

#ifndef WEIGHT

#define WEIGHT

/**

* A very simple weight class (used to demonstrate memory

* allocation for objects)

*

* @author Prof. David Bernstein, James Madison University

* @version 1.0

*/

class Weight

{

public:

int pounds, ounces;

Weight(int lbs, int oz);

};

#endif

cppexamples\memory\Weight.cpp

#include "Weight.h"

/**

* A very simple weight class (used to demonstrate memory

* allocation for objects)

*

* @author Prof. David Bernstein, James Madison University

* @version 1.0

*/

/**

* Explicit Value Constructor

*

* @param lbs The number of pounds in this Weight

* @param oz The number of ounces in this Weight

*/

Weight::Weight(int lbs, int oz)

{

pounds = lbs;

ounces = oz;

}

Dynamic Allocation of Objects (cont.) An Observation:

o We can dynamically allocate memory for objects

An Example:

o

o Weight *w;

o

Illustration:

o

Dynamic Allocation of Objects (cont.) An Example:

o

o w = new Weight(6,11);

o

Illustration:

o

Dynamic Allocation of Objects (cont.) De-referencing Pointers to Objects:

o Works the same as with other pointers

An Example:

o

o (*w).pounds

o

A "Shorthand" Operator:

o

o w->pounds

o

o Inside of a class you can use this->

Dynamic Allocation of Objects (cont.) A More Complicated Class

cppexamples\memory\Person.h

/**

* A person

*

* Author: CS240

* Department of Computer Science

* James Madison University

*

*/

#define PERSON

#include < string.h >

class Person {

public:

char *personalName, *familyName;

int age;

/**

* Constructor

*

* Purpose: Construct a new Person

*

* Arguments: pn - A pointer to the personal name

* fn - A pointer to the family name

* n - The person's age

*

* Side Effect: None

*

* Returns:

*/

Person(char *pn, char*fn, int n);

/**

* Destructor

*

* Purpose: Destroy a new Person

*

* Arguments: None

*

* Side Effect: None

*

* Returns:

*/

~Person(void);

};

cppexamples\memory\Person.cpp

/**

* Implementation of the Person class

*

* Author: CS240

* Department of Computer Science

* James Madison University

*

*/

#ifndef PERSON

#include "Person.h"

#endif

/**

* Constructor

*

* Purpose: Construct a new Person

*

* Arguments: pn - A pointer to the personal name

* fn - A pointer to the family name

* n - The person's age

*

* Side Effect: None

*

* Returns:

*/

Person::Person(char *pn, char*fn, int n) {

personalName = new char[strlen(pn)+1];

familyName = new char[strlen(fn)+1];

strcpy(personalName, pn);

strcpy(familyName, fn);

age = n;

}

/**

* Destructor

*

* Purpose: Destroy a new Person

*

* Arguments: None

*

* Side Effect: None

*

* Returns:

*/

Person::~Person(void) {

// Return memory occupied by the personal name

delete[] personalName;

// Return memory occupied by the family name

delete[] familyName;

}

Dynamic Allocation of Objects (cont.) An Example:

o

o Person *p;

o

Illustration:

o

Dynamic Allocation of Objects (cont.) An Example:

o

o Person *q;

o char *first, *last;

o int age;

o

Illustration:

o

Dynamic Allocation of Objects (cont.) An Example:

o

o first = new char[6];

o last = new char[10];

o age = 26;

o

Illustration:

o

Dynamic Allocation of Objects (cont.) An Example:

o

o strcpy(first, "David");

o strcpy(last, "Bernstein");

o

Illustration:

o

Dynamic Allocation of Objects (cont.) An Example:

o

o q = new Person(first, last, age);

o

Illustration:

o

Dynamic Allocation of Objects (cont.) Returning Memory to the Heap:

o The memory manager doesn't know how many times the object might have requested memory from the heap in its various methods

o The object must keep track of this itself

Destructor:

o A method with the job of returning all "supplemental" memory used by an object

o Has the same name as the class but preceeded by a tilde (i.e., the ~ character)

o Whenever the delete operator is applied to a pointer to an object the object's destructor

is called

Dynamic Allocation of C Strings Recall:

o Strings (in C) are just arrays of characters terminated with a '\0'

An Example:

o

o char *s;

o

o s = new char[20];

o

Dynamic Allocation of C Strings (cont.) A Static Array of Dynamically Allocated Strings:

o

o char *names[4];

o int nameLength;

o

o nameLength = 80;

o

o for (int i=0; i<4; i++) names[i] = new char[nameLength];

o

o strcpy(names[0],"Alice");

o strcpy(names[1],"Bob");

o strcpy(names[2],"Carol");

o strcpy(names[3],"Dan");

o

Dynamic Allocation of Arrays of Objects An Example:

o

o int numWeights;

o Weight *w;

o

o numWeights = 50;

o

o w = new Weight[numWeights];

o

Interpretation:

o w is a pointer to the array

o Each element of w is a Weight object (not a reference to a Weight)

o Each Weight is constructed using the default constructor

An Aside on main So Far:

o Our main function has had no parameters

Now:

o We can discuss a version of main that is passed command-line arguments

o int main(int argc, const char *argv[])

top related