#include <iostream>
#include <string>
#include <string>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cstring>
#include <string>
#include <vector>
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 t = 0)
{
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 (t != 0 && q->size != t) {
fprintf(stderr, "xfree(): bad size. expected %d, but %d\n", q->size, t);
}
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_GLOBAL 1001
void *operator new(size_t size) {
printf("new: GLOBAL size = %d\n", (int)size);
return xmalloc(size, ID_GLOBAL);
}
void operator delete(void *p) {
printf("delete1: GLOBAL\n");
xfree(p, ID_GLOBAL);
}
void operator delete(void *p, std::size_t t) {
printf("delete2: GLOBAL\n");
xfree(p, ID_GLOBAL, t);
}
/*--------------------------------------------------------------------------------------------*/
#include <iostream>
#include <vector>
#include <string>
#include <memory>
class Visitor;
class Entry {
public:
virtual ~Entry() {};
virtual std::string getName() const = 0;
virtual size_t getSize() = 0;
virtual size_t accept(std::shared_ptr<Visitor>) = 0;
};
template <class T>
class Iterator {
public:
virtual ~Iterator() {}
virtual bool hasNext() = 0;
virtual T next() = 0;
};
template <class T>
class VectorIterator : public Iterator<T> {
std::vector<T> &v;
size_t index = 0;
public:
VectorIterator(std::vector<T> &v) : v(v) {}
bool hasNext() override {
if (index < v.size())
return true;
else
return false;
}
T next() {
T retvalue = v[index];
index++;
return retvalue;
}
};
class File : public Entry {
std::string name;
size_t size;
public:
File(std::string name, size_t size) : name(name), size(size) {}
File(const File &ob) { this->name = ob.name; this->size = ob.size; }
File(const File *p) { this->name = p->name; this->size = p->size; }
std::string getName() const override { return name; }
size_t getSize() override { return size; }
size_t accept(std::shared_ptr<Visitor>) override;
};
class Directory : public Entry {
std::string name;
std::vector<std::shared_ptr<Entry>> v;
public:
Directory(std::string name) : name(name) {}
Directory(const Directory &ob) { this->name = ob.name; this->v = ob.v; }
Directory(const Directory *p) { this->name = p->name; this->v = p->v; }
// ~Directory() {
// for (auto p : v) delete p;
// }
std::string getName() const override { return name; }
size_t getSize() override;
size_t accept(std::shared_ptr<Visitor> v) override;
void treePrint();
void add(std::shared_ptr<Entry> entry) { v.push_back(entry); }
std::shared_ptr<Iterator<std::shared_ptr<Entry>>> iterator() { return std::make_shared<VectorIterator<std::shared_ptr<Entry>>>(v); }
};
class Visitor {
public:
virtual ~Visitor() {}
virtual size_t visit(std::shared_ptr<File>) = 0;
virtual size_t visit(std::shared_ptr<Directory>) = 0;
};
size_t File::accept(std::shared_ptr<Visitor> v) { return v->visit(std::make_shared<File>(this)); }
size_t Directory::accept(std::shared_ptr<Visitor> v) { return v->visit(std::make_shared<Directory>(this)); }
class SizeVisitor : public Visitor {
public:
SizeVisitor() {};
SizeVisitor(const SizeVisitor &) {}
SizeVisitor(const SizeVisitor *) {}
size_t visit(std::shared_ptr<File> file) { return file->getSize(); }
size_t visit(std::shared_ptr<Directory> directory) {
size_t size = 0;
std::shared_ptr<Iterator<std::shared_ptr<Entry>>> it = directory->iterator();
while (it->hasNext()) {
std::shared_ptr<Entry> entry = it->next();
size += entry->accept(std::make_shared<SizeVisitor>(this));
}
// delete it;
return size;
}
};
class ListVisitor : public Visitor {
std::string currentDirectoryName;
std::string saveDirectoryName;
public:
ListVisitor() {}
ListVisitor(const ListVisitor &ob) {
this->currentDirectoryName = ob.currentDirectoryName;
this->saveDirectoryName = ob.saveDirectoryName;
}
ListVisitor(const ListVisitor *p) {
this->currentDirectoryName = p->currentDirectoryName;
this->saveDirectoryName = p->saveDirectoryName;
}
size_t visit(std::shared_ptr<File> file) {
std::cout << currentDirectoryName << "/" << file->getName() << "(" << file->getSize() << ")" << std::endl;
return 0;
}
size_t visit(std::shared_ptr<Directory> dir) {
std::cout << currentDirectoryName << "/" << dir->getName() << "(" << dir->getSize() << ")" << std::endl;
saveDirectoryName = currentDirectoryName;
currentDirectoryName += "/" + dir->getName();
std::shared_ptr<Iterator<std::shared_ptr<Entry>>> it = dir->iterator();
while (it->hasNext()) {
std::shared_ptr<Entry> entry = it->next();
entry->accept(std::make_shared<ListVisitor>(this));
}
// delete it;
currentDirectoryName = saveDirectoryName;
return 0;
}
};
size_t Directory::getSize() {
auto visitor = std::make_shared<SizeVisitor>();
size_t size = this->accept(visitor);
// delete visitor;
return size;
}
void Directory::treePrint() {
auto visitor = std::make_shared<ListVisitor>();
this->accept(visitor);
// delete visitor;
}
int main() {
{
auto rootdir = std::make_shared<Directory>("root");
auto file1 = std::make_shared<File>("file1.txt", 100);
auto file2 = std::make_shared<File>("file2.txt", 200);
rootdir->add(file1);
rootdir->add(file2);
rootdir->treePrint();
// delete rootdir;
}
xmallocdump();
return 0;
}