#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
//#include <cstdio>
//#include <cstdlib>
//#include <cctype>
//#include <cstring>
#include <iostream>
struct supernode {
int id;
unsigned int size;
void *data;
struct supernode *next;
struct supernode *before;
};
static struct supernode *superrootS = NULL;
#define N 16
void xmallocdump(void)
{
int i;
unsigned char c;
struct supernode *p;
if (superrootS == NULL) {
fprintf(stderr, "xmallocdump(): root is NULL.\n");
} else {
p = superrootS;
fprintf(stderr, "ERROR: Memory leak occured!\n");
do {
fprintf(stderr, "Memory Leak >%p %p %p(%d):%d: ", (void *)p, (void *)p->next, p->data, p->size, p->id);
for (i = 0; i < N; i++) {
c = *(unsigned char *)((char *)(p->data) + i);
printf("%02x(%c) ", c , (isprint(c)) ? c : '.');
}
putchar('\n');
p = p->next;
} while (p != superrootS);
}
}
void *xmalloc(unsigned int n, int id)
{
unsigned int i;
struct supernode *p;
rand();
if ((p = (struct supernode *)malloc(sizeof(struct supernode))) == NULL) {
fprintf(stderr, "xmalloc(): cannot malloc() in xmalloc()\n");
abort();
}
if (superrootS == NULL) {
superrootS = p;
p->size = n;
p->next = p;
p->before = p;
} else {
p->size = n;
p->next = superrootS->next;
p->before = superrootS;
superrootS->next = p;
p->next->before = p;
}
if ((p->data = (void *)malloc(n)) == NULL) {
fprintf(stderr, "xmalloc(): cannot malloc() in malloc()\n");
abort();
}
for (i = 0; i < n; i++)
*(char *)((char *)(p->data) + i) = (char)(rand() & 0xff);
p->id = id;
//printf("xmalloc():malloc id = %d(%p)\n", p->id, p->data);
return p->data;
}
void xfree(void *p, int id)
{
unsigned int flag, i;
struct supernode *q;
//printf("xfree():free id = %d(%p)\n", id, p);
if (p == NULL)
return;
if (superrootS == NULL) {
fprintf(stderr, "xfree(): root is null.\n");
abort();
}
rand();
flag = 0;
q = superrootS;
for (;;) {
if (q->data == p) {
if (q->id != id) {
fprintf(stderr, "xfree(): bad ID. expected %d, but %d\n", q->id, id);
}
if (q->next == q) {
for (i = 0; i < q->size; i++)
*(char *)((char *)(q->data) + i) = (char)(rand() & 0xff);
free(q->data);
free(q);
flag = 1;
superrootS = NULL;
break;
} else {
q->before->next = q->next;
q->next->before = q->before;
if (q == superrootS)
superrootS = q->next;
for (i = 0; i < q->size; i++)
*(char *)((char *)(q->data) + i) = (char)(rand() & 0xff);
free(q->data);
free(q);
flag = 1;
break;
}
}
if (q->next == superrootS)
break;
q = q->next;
}
if (flag != 1) {
fprintf(stderr, "xfree(): cannot xfree(), no data.(id = %d, %p)\n", id, p);
abort();
}
}
/*--------------------------------------------------------------------------------------------*/
#define ID_BOOK 1001
#define ID_LIST 1002
#define ID_ARRAY 1003
#define ID_CITERATOR 1004
#define ID_GLOBAL 1005
#if 1
void *operator new(size_t size) {
printf("new: GLOBAL size = %d\n", size);
return xmalloc(size, ID_GLOBAL);
}
void operator delete(void *p) {
printf("delete: GLOBAL\n");
xfree(p, ID_GLOBAL);
}
#endif
/*--------------------------------------------------------------------------------------------*/
template <class T>
class Iterator {
public:
virtual bool hasNext() = 0;
virtual T *next() = 0;
virtual ~Iterator() { };
};
template <class T>
class Aggregate {
public:
virtual Iterator<T> *iterator() = 0;
virtual ~Aggregate() { };
};
/*--------------------------------------------------------------------------------------------*/
class Book {
char *name;
public:
Book(char const *p) {
this->name = new char [::strlen(p) + 1];
strcpy(this->name, p);
}
~Book() { delete [] name; }
char *getName() { return name; };
static void *operator new(size_t size) {
void *p;
p = xmalloc(size, ID_BOOK);
printf("new: Book size = %d, %p\n", size, p);
return p;
}
static void operator delete(void *p) {
printf("delete: Book, %p\n", p);
xfree(p, ID_BOOK);
}
};
/*--------------------------------------------------------------------------------------------*/
template <class T>
class mylist {
T *data;
struct mylist *next;
public:
mylist(T *data) {
this->data = data;
this->next = 0;
}
static void *operator new(size_t size) {
printf("new: mylist size = %d\n", size);
return xmalloc(size, ID_LIST);
}
static void operator delete(void *p) {
printf("delete: mylist\n");
xfree(p, ID_LIST);
}
static void release(mylist<T> **root) {
delete (*root)->data;
if ((*root)->next) {
release(&((*root)->next));
(*root)->next = 0;
}
delete *root;
}
static void append(mylist<T> **root, T *data) {
if (!*root)
*root = new mylist(data);
else
append(&((*root)->next), data);
}
static T *getData(mylist<T> *p) { return p->data; }
static mylist<T> *getNextList(mylist<T> *p) { return p->next; }
};
template<class T>
class Array : public Aggregate<T> {
mylist<T> *books;
public:
Array() {
books = 0;
}
~Array() {
if (books) {
mylist<T>::release(&books);
books = 0;
}
}
static void *operator new(size_t size) {
printf("new: Array size = %d\n", size);
return xmalloc(size, ID_ARRAY);
}
static void operator delete(void *p) {
printf("delete: Array\n");
xfree(p, ID_ARRAY);
}
void append(T *data) { mylist<T>::append(&books, data); };
mylist<T> *setArrayRoot() { return books; }
mylist<T> *pointNext(mylist<T> *p) { return mylist<T>::getNextList(p); }
//
Iterator<T> *iterator(); //(b);
};
/*--------------------------------------------------------------------------------------------*/
template<class T>
class ConcreteIterator : public Iterator<T> {
Array<T> *bookShelf;
mylist<T> *p;
public:
ConcreteIterator(Array<T> *bookShelf) {
this->bookShelf = bookShelf;
this->p = this->bookShelf->setArrayRoot();
}
static void *operator new(size_t size) {
printf("new: ConcreteIterator size = %d\n", size);
return xmalloc(size, ID_CITERATOR);
}
static void operator delete(void *p) {
printf("delete: ConcreteIterator\n");
xfree(p, ID_CITERATOR);
}
bool hasNext() {
if (p != 0)
return true;
else
return false;
}
T *next() {
T *book = mylist<T>::getData(p);
p = bookShelf->pointNext(p);
return book;
}
};
template<class T>
Iterator<T> *Array<T>::iterator() {
return new ConcreteIterator<T>(this); //(c)
}
/*--------------------------------------------------------------------------------------------*/
int main() {
Array<Book> *bookShelf = new Array<Book>();
bookShelf->append(new Book("test1"));
bookShelf->append(new Book("test2"));
bookShelf->append(new Book("test3"));
bookShelf->append(new Book("test4"));
Iterator<Book> *itr = bookShelf->iterator(); //(a)
while (itr->hasNext()) {
Book *book = itr->next();
std::cout << book->getName() << std::endl;
}
delete itr; //(d)
delete bookShelf;
std::cout << std::endl;
fflush(stdout);
xmallocdump();
return 0;
}
/* end */