User Tools

Site Tools


notes:stl_allocation_example

This is an old revision of the document!


STL Allocation Example

These small pieces of C++ code illustrate how STL structures use copy-constructors and assignment to move items into place, and how the swap() method doesn't require any copies or assignments.

std::list

stl_copy_list.cpp
#include <list>
#include <stdio.h>
 
class MyClass
{
public:
  MyClass(int id);
  MyClass(const MyClass &other);
  ~MyClass();
  MyClass& operator=(const MyClass &other);
  int getID() const { return myID; }
private:
  MyClass() { };
  int myID;
};
 
MyClass::MyClass(int id) : myID(id)
{
  printf("%p: MyClass(%d)\n", this, myID);
}
 
MyClass::MyClass(const MyClass &other) : myID(other.myID)
{
  printf("%p: MyClass(MyClass(%d))\n", this, myID);
}
 
MyClass::~MyClass()
{
  printf("%p: ~MyClass(%d)\n", this, myID);
}
 
MyClass& MyClass::operator=(const MyClass &other)
{
  myID = other.myID;
  printf("%p: MyClass = MyClass(%d)\n", this, myID);
  return *this;
}
 
int main()
{
  std::list<MyClass> one;
  std::list<MyClass> two;
 
  printf("Adding 11 to one\n");
  one.push_back(MyClass(11));
  printf("Adding 12 to one\n");
  one.push_back(MyClass(12));
  printf("Adding 21 to two\n");
  two.push_back(MyClass(21));
  printf("Adding 22 to two\n");
  two.push_back(MyClass(22));
 
  printf("Contents of one:\n");
  for (std::list<MyClass>::iterator it = one.begin(); it != one.end(); ++it) {
    printf("  %d\n", it->getID());
  }
  printf("Contents of two:\n");
  for (std::list<MyClass>::iterator it = two.begin(); it != two.end(); ++it) {
    printf("  %d\n", it->getID());
  }
 
  printf("Calling one.swap(two)\n");
  one.swap(two);
 
  printf("Contents of one:\n");
  for (std::list<MyClass>::iterator it = one.begin(); it != one.end(); ++it) {
    printf("  %d\n", it->getID());
  }
  printf("Contents of two:\n");
  for (std::list<MyClass>::iterator it = two.begin(); it != two.end(); ++it) {
    printf("  %d\n", it->getID());
  }
 
  printf("Clearing two\n");
  two.clear();
 
  printf("Exiting now\n");
  return 0;
}

Typical output

Adding 11 to one
0x7fff02969ea0: MyClass(11)
0xed8020: MyClass(MyClass(11))
0x7fff02969ea0: ~MyClass(11)
Adding 12 to one
0x7fff02969eb0: MyClass(12)
0xed8040: MyClass(MyClass(12))
0x7fff02969eb0: ~MyClass(12)
Adding 21 to two
0x7fff02969ec0: MyClass(21)
0xed8060: MyClass(MyClass(21))
0x7fff02969ec0: ~MyClass(21)
Adding 22 to two
0x7fff02969ed0: MyClass(22)
0xed8080: MyClass(MyClass(22))
0x7fff02969ed0: ~MyClass(22)
Contents of one:
  11
  12
Contents of two:
  21
  22
Calling one.swap(two)
Contents of one:
  21
  22
Contents of two:
  11
  12
Clearing two
0xed8020: ~MyClass(11)
0xed8040: ~MyClass(12)
Exiting now
0xed8060: ~MyClass(21)
0xed8080: ~MyClass(22)

std::map

stl_copy_map.cpp
#include <map>
#include <stdio.h>
 
class MyClass
{
public:
  MyClass();
  MyClass(int id);
  MyClass(const MyClass &other);
  ~MyClass();
  MyClass& operator=(const MyClass &other);
  int getID() const { return myID; }
private:
  int myID;
};
 
MyClass::MyClass() : myID(-1)
{
  printf("%p: MyClass()\n", this);
}
 
MyClass::MyClass(int id) : myID(id)
{
  printf("%p: MyClass(%d)\n", this, myID);
}
 
MyClass::MyClass(const MyClass &other) : myID(other.myID)
{
  printf("%p: MyClass(%p: MyClass(%d))\n", this, &other, myID);
}
 
MyClass::~MyClass()
{
  printf("%p: ~MyClass(%d)\n", this, myID);
}
 
MyClass& MyClass::operator=(const MyClass &other)
{
  myID = other.myID;
  printf("%p: MyClass = %p: MyClass(%d)\n", this, &other, myID);
 
  return *this;
}
 
 
int main()
{
  std::map<int, MyClass> one;
  std::map<int, MyClass> two;
 
  printf("Adding 11 to one\n");
  one[11] = MyClass(11);
  printf("Adding 12 to one\n");
  one[12] = MyClass(12);
  printf("Adding 21 to two\n");
  two[21] = MyClass(21);
  printf("Adding 22 to two\n");
  two[22] = MyClass(22);
 
  printf("Contents of one:\n");
  for (std::map<int, MyClass>::iterator it = one.begin();
       it != one.end(); ++it) {
    printf("  %d: %d\n", it->first, it->second.getID());
  }
  printf("Contents of two:\n");
  for (std::map<int, MyClass>::iterator it = two.begin();
       it != two.end(); ++it) {
    printf("  %d: %d\n", it->first, it->second.getID());
  }
 
  printf("Calling one.swap(two)\n");
  one.swap(two);
 
  printf("Contents of one:\n");
  for (std::map<int, MyClass>::iterator it = one.begin();
       it != one.end(); ++it) {
    printf("  %d: %d\n", it->first, it->second.getID());
  }
  printf("Contents of two:\n");
  for (std::map<int, MyClass>::iterator it = two.begin();
       it != two.end(); ++it) {
    printf("  %d: %d\n", it->first, it->second.getID());
  }
 
  printf("Clearing two\n");
  two.clear();
 
  printf("Exiting now\n");
  return 0;
}

Typical Output

Adding 11 to one
0x7fff67f4ef30: MyClass(11)
0x7fff67f4ee50: MyClass()
0x7fff67f4ee44: MyClass(0x7fff67f4ee50: MyClass(-1))
0x1edb034: MyClass(0x7fff67f4ee44: MyClass(-1))
0x7fff67f4ee44: ~MyClass(-1)
0x7fff67f4ee50: ~MyClass(-1)
0x1edb034: MyClass = 0x7fff67f4ef30: MyClass(11)
0x7fff67f4ef30: ~MyClass(11)
Adding 12 to one
0x7fff67f4ef40: MyClass(12)
0x7fff67f4ee50: MyClass()
0x7fff67f4ee44: MyClass(0x7fff67f4ee50: MyClass(-1))
0x1edb064: MyClass(0x7fff67f4ee44: MyClass(-1))
0x7fff67f4ee44: ~MyClass(-1)
0x7fff67f4ee50: ~MyClass(-1)
0x1edb064: MyClass = 0x7fff67f4ef40: MyClass(12)
0x7fff67f4ef40: ~MyClass(12)
Adding 21 to two
0x7fff67f4ef50: MyClass(21)
0x7fff67f4ee50: MyClass()
0x7fff67f4ee44: MyClass(0x7fff67f4ee50: MyClass(-1))
0x1edb094: MyClass(0x7fff67f4ee44: MyClass(-1))
0x7fff67f4ee44: ~MyClass(-1)
0x7fff67f4ee50: ~MyClass(-1)
0x1edb094: MyClass = 0x7fff67f4ef50: MyClass(21)
0x7fff67f4ef50: ~MyClass(21)
Adding 22 to two
0x7fff67f4ef60: MyClass(22)
0x7fff67f4ee50: MyClass()
0x7fff67f4ee44: MyClass(0x7fff67f4ee50: MyClass(-1))
0x1edb0c4: MyClass(0x7fff67f4ee44: MyClass(-1))
0x7fff67f4ee44: ~MyClass(-1)
0x7fff67f4ee50: ~MyClass(-1)
0x1edb0c4: MyClass = 0x7fff67f4ef60: MyClass(22)
0x7fff67f4ef60: ~MyClass(22)
Contents of one:
  11: 11
  12: 12
Contents of two:
  21: 21
  22: 22
Calling one.swap(two)
Contents of one:
  21: 21
  22: 22
Contents of two:
  11: 11
  12: 12
Clearing two
0x1edb064: ~MyClass(12)
0x1edb034: ~MyClass(11)
Exiting now
0x1edb0c4: ~MyClass(22)
0x1edb094: ~MyClass(21)
notes/stl_allocation_example.1361811488.txt.gz · Last modified: 2013/02/25 16:58 by andy