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
*/