1-3) Memory
Revisions:
May
21, 2008 modified c-style string example
Stack vs.
Heap
Objects
The following statements declare memory on the
Procedure
Stack.
Stack memory is allocated in any statement of the
form: Type variableName
int x;
Person me;
Person *p;
Person people[100];
Person(); //an anonymous stack object;
foo( Person() ); //creating a temporary function
argument
The following statements declare memory on the
Heap
(Dynamic Memory)
Dynamic memory is allocated in any statement of the
form: new Type
int * i = new int;
Person *p = new Person("Lou");
Person *p = new Person[100];
Note: the following statements are equivalent
Person* p;
Person * p;
Person *p;
The following statements are NOT equivalent
Person* p,q;
Person *p, *q;
Dynamic Memory in C++ is
allocated
with new and removed with delete
Examples:
BankAccount * p = new BankAccount("Lou");
...later
delete p;
BankAccount * accounts = new BankAccount[100];
//Will require a default BankAccount constructor
...later
delete [] accounts
Example of dynamic array allocation in C++
//example for allocating, using, and deleting
a
3*5
//dynamic array
#include <iostream>
using namespace std;
int main(void) {
int **a; //pointer to int *
//allocate dynamic 3*5 array
a = new int*[3];
for (int i=0; i<3;i++)
a[i] = new int[5];
//put some numbers in the array
for (i = 0; i<3; i++)
for (int j = 0;
j<5; j++)
a[i][j]
= i * j;
//print the array
for (i = 0; i<3; i++) {
for (int j = 0; j<5; j++)
cout
<<
a[i][j];
cout << "\n";
}
//delete the dynamic array
for(i = 0; i<3;i++)
delete [] a[i];
delete [] a;
return 0;
}
Using C-style Strings
(Example)
#include
<iostream>
#include
<cstring>
//for strcmp(),
strcpy(), strlen(), strcat()
using
namespace
std;
int
main() {
char
input[100];
char
* myString;
cout << "enter an
input string" <<
endl;
cin >> input;
cout << "you
said: ";
cout << input << endl;
cout << "the
length of your string is " << strlen(input) << endl;
myString = new
char[strlen(input)
+ 1];
strcpy(myString, input);
cout << "the
length of myString is " << strlen(myString) << endl;
cout << myString << endl;
//comparing strings
cout << strcmp("abba",
myString) << endl;
cout << strcmp(myString, myString) << endl;
cout << strcmp(myString,
"abba") << endl;
return
0;
}
/* Program output
enter an input string
Saturday
you said: Saturday
the length of your string is 8
the length of myString is 8
Saturday
1
0
-1
*/
Example of Dynamic Memory for C-style string variables in
a class
#include
<iostream>
#include
<cstring>
//for strcmp(),
strcpy(), strlen(), strcat()
using
namespace
std;
class
Person {
public:
Person(char
* their_name = "unknown",
char * email =
"unknown"){
name = new
char[strlen(their_name)
+ 1];
strcpy(name, their_name);
email_address =
new
char[strlen(email)
+ 1];
strcpy(email_address, email);
}
~Person(
void)
{
delete
[] name;
delete
[] email_address;
}
char * getEmailAddress(){return
email_address;}
char *
getName() {return
name;}
private:
char *
name;
char
* email_address;
};
void
main(){
Person lou("Lou",
"lou@hotmail.com");
Person sue("Sue",
"sue@scs.carleton.ca");
Person p;
cout << lou.getName() <<
" email: " <<
lou.getEmailAddress() << endl;
cout << sue.getName() <<
" email: "
<< sue.getEmailAddress() << endl;
cout << p.getName() << " email: "
<< p.getEmailAddress() << endl;
}
/* output
Lou email: lou@hotmail.com
Sue email: sue@scs.carleton.ca
unknown email: unknown
*/
Linked List
(Example)
//File
linkedlist.cpp
//--------------------
//simple
illustration of a Linked List with no attempt to use
//classes
or encapsulation (i.e. no object-oriented features)
#include <iostream.h>
struct Node { //same as: class Node {public:
int element; //data
Node
*next; //pointer to next
node
};
struct List { //same as: class List { public:
Node *top; //top of the list, NULL when list is
empty
};
bool isEmpty(List & theList) {
return
theList.top == 0;
}
void destroy(List & theList)
//release
all the nodes of the list and mark it as empty
{
Node *nodeptr;
while (theList.top != 0) {
nodeptr =
theList.top;
theList.top =
theList.top->next;
cout <<
"deleting: " << nodeptr->element << "\n";
delete nodeptr;
}
}
void append(List & theList,
const int & item)
//append
item to the end of the list
{
if(isEmpty(theList)) {
theList.top = new Node;
theList.top->element = item;
theList.top->next = NULL;
return;
}
Node *nodeptr =
theList.top;
while (nodeptr->next !=
0) {
nodeptr =
nodeptr->next;
}
nodeptr->next = new
Node;
nodeptr = nodeptr->next;
nodeptr->element = item;
nodeptr->next = NULL;
}
int indexOf(List & theList,
const int & item)
//answer
the index, starting from zero, of the first occurence
//of item
in the list, answer -1 if item is not found
{
if(isEmpty(theList))
return -1;
int count = 0;
Node *nodeptr =
theList.top;
while (nodeptr != 0) {
if
(nodeptr->element == item ) return count;
nodeptr =
nodeptr->next;
count++;
}
return -1; //item was not
found
}
void print(List & theList)
//write
the list to cout
{
Node *nodeptr =
theList.top;
while (nodeptr != 0) {
cout <<
nodeptr->element << "\n";
nodeptr =
nodeptr->next;
}
cout << "\n";
}
//File Test.cpp
//main application to test linked list
#include <iostream.h>
#include "linkedlist.cpp"
void main (void)
{
List list;
list.top = 0; //initialize the list to empty
append(list, 2); //append some items to the list
append(list, 13);
append(list, 42);
append(list, 96);
print(list); //print the list
destroy(list); //destroy the list and release dynamic
memory
append(list, 100); //append some new items
append(list, 200);
append(list, 300);
append(list, 400);
print(list); //print the list
//obtain
the indices of some entries
cout << "index of 100 is "
<< indexOf(list, 100) << "\n";
cout << "index of 300 is "
<< indexOf(list, 300) << "\n";
cout << "index of 400 is "
<< indexOf(list, 400) << "\n";
cout << "index of 600 is "
<< indexOf(list, 600) << "\n";
destroy(list); //destroy the list and release dynamic
memory
}
/*
Program
output
2
13
42
96
deleting: 2
deleting:
13
deleting:
42
deleting:
96
100
200
300
400
index of
100 is 0
index of
300 is 2
index of
400 is 3
index of
600 is -1
deleting:
100
deleting:
200
deleting:
300
deleting:
400
*/