fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <string>
  4. #include <map>
  5. #include <cstdio>
  6. #include <cstdlib>
  7. #include <cstring>
  8. #include <cctype>
  9. #include <cstring>
  10. #include <string>
  11. #include <vector>
  12.  
  13. struct supernode {
  14. int id;
  15. unsigned int size;
  16. void *data;
  17. struct supernode *next;
  18. struct supernode *before;
  19. };
  20.  
  21. static struct supernode *superrootS = NULL;
  22.  
  23. #define N 16
  24. void xmallocdump(void)
  25. {
  26. int i;
  27. unsigned char c;
  28. struct supernode *p;
  29. if (superrootS == NULL) {
  30. fprintf(stderr, "xmallocdump(): root is NULL.\n");
  31. } else {
  32. p = superrootS;
  33. fprintf(stderr, "ERROR: Memory leak occured!\n");
  34. do {
  35. fprintf(stderr, "Memory Leak >%p %p %p(%d):%d: ", (void *)p, (void *)p->next, p->data, p->size, p->id);
  36. for (i = 0; i < N; i++) {
  37. c = *(unsigned char *)((char *)(p->data) + i);
  38. printf("%02x(%c) ", c , (isprint(c)) ? c : '.');
  39. }
  40. putchar('\n');
  41. p = p->next;
  42. } while (p != superrootS);
  43. }
  44. }
  45.  
  46. void *xmalloc(unsigned int n, int id)
  47. {
  48. unsigned int i;
  49. struct supernode *p;
  50. rand();
  51. if ((p = (struct supernode *)malloc(sizeof(struct supernode))) == NULL) {
  52. fprintf(stderr, "xmalloc(): cannot malloc() in xmalloc()\n");
  53. abort();
  54. }
  55. if (superrootS == NULL) {
  56. superrootS = p;
  57. p->size = n;
  58. p->next = p;
  59. p->before = p;
  60. } else {
  61. p->size = n;
  62. p->next = superrootS->next;
  63. p->before = superrootS;
  64. superrootS->next = p;
  65. p->next->before = p;
  66. }
  67. if ((p->data = (void *)malloc(n)) == NULL) {
  68. fprintf(stderr, "xmalloc(): cannot malloc() in malloc()\n");
  69. abort();
  70. }
  71. for (i = 0; i < n; i++)
  72. *(char *)((char *)(p->data) + i) = (char)(rand() & 0xff);
  73. p->id = id;
  74. //printf("xmalloc():malloc id = %d(%p)\n", p->id, p->data);
  75. return p->data;
  76. }
  77.  
  78. void xfree(void *p, int id, unsigned int t = 0)
  79. {
  80. unsigned int flag, i;
  81. struct supernode *q;
  82. //printf("xfree():free id = %d(%p)\n", id, p);
  83. if (p == NULL)
  84. return;
  85. if (superrootS == NULL) {
  86. fprintf(stderr, "xfree(): root is null.\n");
  87. abort();
  88. }
  89. rand();
  90. flag = 0;
  91. q = superrootS;
  92. for (;;) {
  93. if (q->data == p) {
  94. if (q->id != id) {
  95. fprintf(stderr, "xfree(): bad ID. expected %d, but %d\n", q->id, id);
  96. }
  97. if (t != 0 && q->size != t) {
  98. fprintf(stderr, "xfree(): bad size. expected %d, but %d\n", q->size, t);
  99. }
  100. if (q->next == q) {
  101. for (i = 0; i < q->size; i++)
  102. *(char *)((char *)(q->data) + i) = (char)(rand() & 0xff);
  103. free(q->data);
  104. free(q);
  105. flag = 1;
  106. superrootS = NULL;
  107. break;
  108. } else {
  109. q->before->next = q->next;
  110. q->next->before = q->before;
  111. if (q == superrootS)
  112. superrootS = q->next;
  113. for (i = 0; i < q->size; i++)
  114. *(char *)((char *)(q->data) + i) = (char)(rand() & 0xff);
  115. free(q->data);
  116. free(q);
  117. flag = 1;
  118. break;
  119. }
  120. }
  121. if (q->next == superrootS)
  122. break;
  123. q = q->next;
  124. }
  125. if (flag != 1) {
  126. fprintf(stderr, "xfree(): cannot xfree(), no data.(id = %d, %p)\n", id, p);
  127. abort();
  128. }
  129. }
  130.  
  131. /*--------------------------------------------------------------------------------------------*/
  132. #define ID_GLOBAL 1001
  133.  
  134. void *operator new(size_t size) {
  135. printf("new: GLOBAL size = %d\n", (int)size);
  136. return xmalloc(size, ID_GLOBAL);
  137. }
  138. void operator delete(void *p) {
  139. printf("delete1: GLOBAL\n");
  140. xfree(p, ID_GLOBAL);
  141. }
  142.  
  143. void operator delete(void *p, std::size_t t) {
  144. printf("delete2: GLOBAL\n");
  145. xfree(p, ID_GLOBAL, t);
  146. }
  147.  
  148. /*--------------------------------------------------------------------------------------------*/
  149. #include <iostream>
  150. #include <vector>
  151. #include <string>
  152. #include <memory>
  153.  
  154. class Visitor;
  155.  
  156. class Entry {
  157. public:
  158. virtual ~Entry() {};
  159. virtual std::string getName() const = 0;
  160. virtual size_t getSize() = 0;
  161. virtual size_t accept(std::shared_ptr<Visitor>) = 0;
  162. };
  163.  
  164. template <class T>
  165. class Iterator {
  166. public:
  167. virtual ~Iterator() {}
  168. virtual bool hasNext() = 0;
  169. virtual T next() = 0;
  170. };
  171.  
  172. template <class T>
  173. class VectorIterator : public Iterator<T> {
  174. std::vector<T> &v;
  175. size_t index = 0;
  176. public:
  177. VectorIterator(std::vector<T> &v) : v(v) {}
  178. bool hasNext() override {
  179. if (index < v.size())
  180. return true;
  181. else
  182. return false;
  183. }
  184. T next() {
  185. T retvalue = v[index];
  186. index++;
  187. return retvalue;
  188. }
  189. };
  190.  
  191. class File : public Entry {
  192. std::string name;
  193. size_t size;
  194. public:
  195. File(std::string name, size_t size) : name(name), size(size) {}
  196. File(const File &ob) { this->name = ob.name; this->size = ob.size; }
  197. File(const File *p) { this->name = p->name; this->size = p->size; }
  198. std::string getName() const override { return name; }
  199. size_t getSize() override { return size; }
  200. size_t accept(std::shared_ptr<Visitor>) override;
  201. };
  202.  
  203. class Directory : public Entry {
  204. std::string name;
  205. std::vector<std::shared_ptr<Entry>> v;
  206. public:
  207. Directory(std::string name) : name(name) {}
  208. Directory(const Directory &ob) { this->name = ob.name; this->v = ob.v; }
  209. Directory(const Directory *p) { this->name = p->name; this->v = p->v; }
  210.  
  211. // ~Directory() {
  212. // for (auto p : v) delete p;
  213. // }
  214. std::string getName() const override { return name; }
  215. size_t getSize() override;
  216. size_t accept(std::shared_ptr<Visitor> v) override;
  217. void treePrint();
  218. void add(std::shared_ptr<Entry> entry) { v.push_back(entry); }
  219. std::shared_ptr<Iterator<std::shared_ptr<Entry>>> iterator() { return std::make_shared<VectorIterator<std::shared_ptr<Entry>>>(v); }
  220. };
  221.  
  222. class Visitor {
  223. public:
  224. virtual ~Visitor() {}
  225. virtual size_t visit(std::shared_ptr<File>) = 0;
  226. virtual size_t visit(std::shared_ptr<Directory>) = 0;
  227. };
  228.  
  229. size_t File::accept(std::shared_ptr<Visitor> v) { return v->visit(std::make_shared<File>(this)); }
  230. size_t Directory::accept(std::shared_ptr<Visitor> v) { return v->visit(std::make_shared<Directory>(this)); }
  231.  
  232. class SizeVisitor : public Visitor {
  233.  
  234. public:
  235. SizeVisitor() {};
  236. SizeVisitor(const SizeVisitor &) {}
  237. SizeVisitor(const SizeVisitor *) {}
  238. size_t visit(std::shared_ptr<File> file) { return file->getSize(); }
  239. size_t visit(std::shared_ptr<Directory> directory) {
  240. size_t size = 0;
  241. std::shared_ptr<Iterator<std::shared_ptr<Entry>>> it = directory->iterator();
  242. while (it->hasNext()) {
  243. std::shared_ptr<Entry> entry = it->next();
  244. size += entry->accept(std::make_shared<SizeVisitor>(this));
  245. }
  246. // delete it;
  247. return size;
  248. }
  249. };
  250.  
  251. class ListVisitor : public Visitor {
  252. std::string currentDirectoryName;
  253. std::string saveDirectoryName;
  254.  
  255. public:
  256. ListVisitor() {}
  257. ListVisitor(const ListVisitor &ob) {
  258. this->currentDirectoryName = ob.currentDirectoryName;
  259. this->saveDirectoryName = ob.saveDirectoryName;
  260. }
  261. ListVisitor(const ListVisitor *p) {
  262. this->currentDirectoryName = p->currentDirectoryName;
  263. this->saveDirectoryName = p->saveDirectoryName;
  264. }
  265. size_t visit(std::shared_ptr<File> file) {
  266. std::cout << currentDirectoryName << "/" << file->getName() << "(" << file->getSize() << ")" << std::endl;
  267. return 0;
  268. }
  269. size_t visit(std::shared_ptr<Directory> dir) {
  270. std::cout << currentDirectoryName << "/" << dir->getName() << "(" << dir->getSize() << ")" << std::endl;
  271. saveDirectoryName = currentDirectoryName;
  272. currentDirectoryName += "/" + dir->getName();
  273. std::shared_ptr<Iterator<std::shared_ptr<Entry>>> it = dir->iterator();
  274. while (it->hasNext()) {
  275. std::shared_ptr<Entry> entry = it->next();
  276. entry->accept(std::make_shared<ListVisitor>(this));
  277. }
  278. // delete it;
  279. currentDirectoryName = saveDirectoryName;
  280. return 0;
  281. }
  282. };
  283.  
  284. size_t Directory::getSize() {
  285. auto visitor = std::make_shared<SizeVisitor>();
  286. size_t size = this->accept(visitor);
  287. // delete visitor;
  288. return size;
  289. }
  290. void Directory::treePrint() {
  291. auto visitor = std::make_shared<ListVisitor>();
  292. this->accept(visitor);
  293. // delete visitor;
  294. }
  295.  
  296. int main() {
  297. {
  298. auto rootdir = std::make_shared<Directory>("root");
  299. auto file1 = std::make_shared<File>("file1.txt", 100);
  300. auto file2 = std::make_shared<File>("file2.txt", 200);
  301. rootdir->add(file1);
  302. rootdir->add(file2);
  303. rootdir->treePrint();
  304.  
  305. // delete rootdir;
  306. }
  307. xmallocdump();
  308. return 0;
  309. }
  310.  
  311.  
Success #stdin #stdout #stderr 0.01s 5284KB
stdin
Standard input is empty
stdout
new: GLOBAL size = 80
new: GLOBAL size = 64
new: GLOBAL size = 64
new: GLOBAL size = 16
new: GLOBAL size = 32
delete1: GLOBAL
new: GLOBAL size = 88
new: GLOBAL size = 80
new: GLOBAL size = 32
/root(new: GLOBAL size = 24
new: GLOBAL size = 80
new: GLOBAL size = 32
new: GLOBAL size = 40
new: GLOBAL size = 24
new: GLOBAL size = 64
delete1: GLOBAL
delete1: GLOBAL
new: GLOBAL size = 24
new: GLOBAL size = 64
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
300)
new: GLOBAL size = 40
new: GLOBAL size = 88
new: GLOBAL size = 64
/root/file1.txt(100)
delete1: GLOBAL
delete1: GLOBAL
new: GLOBAL size = 88
new: GLOBAL size = 64
/root/file2.txt(200)
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
delete1: GLOBAL
stderr
xmallocdump(): root is NULL.