├── .github └── workflows │ └── manual.yml ├── .gitignore ├── CODEOWNERS ├── LICENSE.MD ├── LeakTester.h ├── README.md ├── gc_details.h ├── gc_iterator.h ├── gc_pointer.h ├── main.cpp └── make /.github/workflows/manual.yml: -------------------------------------------------------------------------------- 1 | # Workflow to ensure whenever a Github PR is submitted, 2 | # a JIRA ticket gets created automatically. 3 | name: Manual Workflow 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on pull request events but only for the master branch 8 | pull_request_target: 9 | types: [assigned, opened, reopened] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | jobs: 15 | test-transition-issue: 16 | name: Convert Github Issue to Jira Issue 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@master 21 | 22 | - name: Login 23 | uses: atlassian/gajira-login@master 24 | env: 25 | JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} 26 | JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} 27 | JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} 28 | 29 | - name: Create NEW JIRA ticket 30 | id: create 31 | uses: atlassian/gajira-create@master 32 | with: 33 | project: CONUPDATE 34 | issuetype: Task 35 | summary: | 36 | Github PR - nd213 C++ Nanodegree | Repo: CppND-Garbage-Collector | PR# ${{github.event.number}} 37 | description: | 38 | Repo link: https://github.com/${{ github.repository }} 39 | PR no. ${{ github.event.pull_request.number }} 40 | PR title: ${{ github.event.pull_request.title }} 41 | PR description: ${{ github.event.pull_request.description }} 42 | In addition, please resolve other issues, if any. 43 | fields: '{"components": [{"name":"nd213 C++"}], "customfield_16449":"https://classroom.udacity.com/nanodegrees/nd213/dashboard/overview", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' 44 | 45 | - name: Log created issue 46 | run: echo "Issue ${{ steps.create.outputs.issue }} was created" 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .github/** 2 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @udacity/active-public-content -------------------------------------------------------------------------------- /LICENSE.MD: -------------------------------------------------------------------------------- 1 | 2 | Copyright © 2012 - 2021, Udacity, Inc. 3 | 4 | Udacity hereby grants you a license in and to the Educational Content, including but not limited to homework assignments, programming assignments, code samples, and other educational materials and tools (as further described in the Udacity Terms of Use), subject to, as modified herein, the terms and conditions of the Creative Commons **Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)** License located at 5 | [http://creativecommons.org/licenses/by-nc-nd/4.0](http://creativecommons.org/licenses/by-nc-nd/4.0) and successor locations for such license (the "CC License") provided that, in each case, the Educational Content is specifically marked as being subject to the CC License. 6 | Udacity expressly defines the following as falling outside the definition of "non-commercial": 7 | 1. the sale or rental of (i) any part of the Educational Content, (ii) any derivative works based at least in part on the Educational Content, or (iii) any collective work that includes any part of the Educational Content; 8 | 2. the sale of access or a link to any part of the Educational Content without first obtaining informed consent from the buyer (that the buyer is aware that the Educational Content, or such part thereof, is available at the Website free of charge); 9 | 3. providing training, support, or editorial services that use or reference the Educational Content in exchange for a fee; 10 | 4. the sale of advertisements, sponsorships, or promotions placed on the Educational Content, or any part thereof, or the sale of advertisements, sponsorships, or promotions on any website or blog containing any part of the Educational Material, including without limitation any "pop-up advertisements"; 11 | 5. the use of Educational Content by a college, university, school, or other educational institution for instruction where tuition is charged; and 12 | 6. the use of Educational Content by a for-profit corporation or non-profit entity for internal professional development or training. 13 | 14 | 15 | 16 | THE SERVICES AND ONLINE COURSES (INCLUDING ANY CONTENT) ARE PROVIDED "AS IS" AND "AS AVAILABLE" WITH NO REPRESENTATIONS OR WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. YOU ASSUME TOTAL RESPONSIBILITY AND THE ENTIRE RISK FOR YOUR USE OF THE SERVICES, ONLINE COURSES, AND CONTENT. WITHOUT LIMITING THE FOREGOING, WE DO NOT WARRANT THAT (A) THE SERVICES, WEBSITES, CONTENT, OR THE ONLINE COURSES WILL MEET YOUR REQUIREMENTS OR EXPECTATIONS OR ACHIEVE THE INTENDED PURPOSES, (B) THE WEBSITES OR THE ONLINE COURSES WILL NOT EXPERIENCE OUTAGES OR OTHERWISE BE UNINTERRUPTED, TIMELY, SECURE OR ERROR-FREE, (C) THE INFORMATION OR CONTENT OBTAINED THROUGH THE SERVICES, SUCH AS CHAT ROOM SERVICES, WILL BE ACCURATE, COMPLETE, CURRENT, ERROR- FREE, COMPLETELY SECURE OR RELIABLE, OR (D) THAT DEFECTS IN OR ON THE SERVICES OR CONTENT WILL BE CORRECTED. YOU ASSUME ALL RISK OF PERSONAL INJURY, INCLUDING DEATH AND DAMAGE TO PERSONAL PROPERTY, SUSTAINED FROM USE OF SERVICES. 17 | -------------------------------------------------------------------------------- /LeakTester.h: -------------------------------------------------------------------------------- 1 | // MEMORY LEAKAGE TESTER 2 | 3 | #ifndef LEAKAGE_TEST_H 4 | #define LEAKAGE_TEST_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define INCLUDE_NOTIFICATIONS __Tester__::notifications = true 14 | // #define EXCLUDE_NOTIFICATIONS __Tester__::notifications = false 15 | 16 | #define FILE_OUTPUT(name) __Tester__::redirect_output(#name) 17 | #define SCREEN_OUTPUT __Tester__::redirect_output(0) 18 | 19 | namespace __Tester__ { 20 | typedef unsigned long ULong; 21 | struct Info { 22 | void *address; 23 | long line; 24 | std::size_t _size; 25 | bool isArray; 26 | Info *link; 27 | } *alloc_map(0); 28 | int alloc_count(0), dealloc_count(0); 29 | long alloc_total(0), dealloc_total(0), alloc_current(0), 30 | alloc_max(0); 31 | bool notifications(false); 32 | char previous_name[1000] = ""; 33 | FILE *output(stdout); 34 | void redirect_output(const char name[]) { 35 | if(output != stdout) fclose(output); 36 | if(name) { 37 | if(strcmp(name, previous_name)) output = fopen(name, "w"); 38 | else output = fopen(name, "a"); 39 | if(output) { 40 | strcpy(previous_name, name); return; 41 | } 42 | } 43 | output = stdout; 44 | } 45 | void *Alloc(long line, std::size_t _size, bool isArray) { 46 | void *address(std::malloc(_size)); 47 | if(!address) throw std::bad_alloc(); 48 | if(line != -1) { 49 | alloc_count++; 50 | alloc_total += _size; alloc_current += _size; 51 | if(alloc_current > alloc_max) alloc_max = alloc_current; 52 | if(notifications) { 53 | if(line == -2) std::fprintf(output, ">>> Internally allocated "); 54 | else std::fprintf(output, ">>> in %ld. line of the script we have allocated memory with the line: ", line); 55 | std::fprintf(output, "%lu bytes, on address %p\n", (ULong)_size, address); 56 | } 57 | } 58 | Info info = {address, line, _size, isArray, alloc_map}; 59 | if(!(alloc_map = (Info*)std::malloc(sizeof(Info)))) 60 | throw std::bad_alloc(); 61 | *alloc_map = info; 62 | return address; 63 | } 64 | void Dealloc(void *ptr, bool isArray) { 65 | Info *current(alloc_map), *previous(0); 66 | for(; current && current->address != ptr; current = current->link) 67 | previous = current; 68 | if(current) { 69 | if(current->line != -1) { 70 | std::size_t _size(current->_size); 71 | dealloc_count++; 72 | dealloc_total += _size; alloc_current -= _size; 73 | if(notifications) { 74 | std::fprintf(output, ">>> Releasing %lu bytes on address %p\n", 75 | (ULong)_size, ptr); 76 | } 77 | if(isArray != current->isArray) 78 | std::fprintf(output, "*** ERROR: Releasing on address %p %s " 79 | "should be done with delete[]!\n", 80 | ptr, isArray ? "no" : "yes"); 81 | } 82 | if(previous) previous->link = current->link; 83 | else alloc_map = current->link; 84 | std::free(current); std::free(ptr); 85 | } 86 | else if(ptr) { 87 | const std::size_t pomak(sizeof(std::size_t)); 88 | void *ptr1((char*)ptr + (isArray ? pomak : -pomak)); 89 | for(current = alloc_map; current && current->address != ptr1; 90 | current = current->link); 91 | if(current) 92 | std::fprintf(output, "*** ERROR: Releasing on address %p %s should " 93 | "be done with delete[]!\n", ptr1, isArray ? "no" : "yes"); 94 | else 95 | fprintf(output, "*** ERROR: You are trying to release already released space " 96 | "on address %p!\n", ptr); 97 | } 98 | } 99 | void Terminator(); 100 | struct Reporter { 101 | void (*old_terminator)(); 102 | Reporter() : old_terminator(std::set_terminate(Terminator)) {} 103 | ~Reporter() { 104 | std::fprintf(output, "\n\n+---------------+\n| FINAL REPORT: |\n" 105 | "+---------------+\n\nTotal number of allocations: %d\nTotal number of " 106 | "deallocations: %d\nTotal number of allocations in bytes: %ld\n" 107 | "Total number of deallocations in bytes: %ld\nMaximum " 108 | "memory occupation during runtime in bytes: %ld\nMemory occupation " 109 | "upon completion: %ld\n", alloc_count, 110 | dealloc_count, alloc_total, dealloc_total, 111 | alloc_max, alloc_current); 112 | if(alloc_map) { 113 | std::fprintf(output, "\n\nLEAK! YOU HAVE MEMORY LEAKAGE ON FOLLOWING PLACES: \n"); 114 | for(Info *current = alloc_map; current; current = current->link) 115 | if(current->line == -2) 116 | std::fprintf(output, " - address %p, %lu bytes, allocated internally\n", 117 | current->address, (ULong)current->_size); 118 | else 119 | std::fprintf(output, " - address %p, %lu bytes, allocated in %ld. " 120 | "line\n", current->address, (ULong)current->_size, 121 | current->line); 122 | std::fprintf(output, "\n"); 123 | } 124 | else 125 | std::fprintf(output, "\n\nGREAT JOB! YOU DO NOT HAVE MEMORY LEAKAGE\n\n"); 126 | if(output != stdout) fclose(output); 127 | std::system("PAUSE"); 128 | } 129 | } reporter; 130 | void Terminator() { 131 | reporter.Reporter::~Reporter(); 132 | reporter.old_terminator(); 133 | } 134 | } 135 | 136 | void *operator new(std::size_t _size, long line) // throw(std::bad_alloc) 137 | { 138 | return __Tester__::Alloc(line, _size, false); 139 | } 140 | 141 | void* operator new[](std::size_t _size, long line) // throw(std::bad_alloc) 142 | { 143 | return __Tester__::Alloc(line, _size, true); 144 | } 145 | 146 | void *operator new(std::size_t _size) // throw(std::bad_alloc) 147 | { 148 | return __Tester__::Alloc(-2, _size, false); 149 | } // Hvata interne alokacije 150 | 151 | void* operator new[](std::size_t _size) // throw(std::bad_alloc) 152 | { 153 | return __Tester__::Alloc(-2, _size, true); 154 | } 155 | 156 | void operator delete(void *ptr) throw() { 157 | __Tester__::Dealloc(ptr, false); 158 | } 159 | 160 | void operator delete[](void* ptr) throw() { 161 | __Tester__::Dealloc(ptr, true); 162 | } 163 | 164 | void operator delete(void *ptr, long) throw() { // placement delete!!! 165 | __Tester__::Dealloc(ptr, false); 166 | } 167 | 168 | void operator delete[](void* ptr, long) throw() { 169 | __Tester__::Dealloc(ptr, true); 170 | } 171 | 172 | #define new new(__LINE__) 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CppND-Garbage-Collector 2 | The final project for this Memory Management course is to implement your own 3 | version of a smart pointer. You can think of this as implementing your own 4 | garbage collector, to use a concept from other programming languages. Building 5 | this project will help you understand both how to work with pointers and 6 | references, and also why smart pointers are so important to modern C++ 7 | programming. Complete the implementations and verify that your implementation 8 | does not have any memory leaks! 9 | 10 | # Building 11 | To build this project, you will need a C++ compiler. The `make` script provided 12 | assumes the GCC compiler, however you may substitute an equivalent C++ compiler 13 | by adjusting the `make` script as needed. Execute the make script, then run the 14 | compiled executable. 15 | 16 | If the code fails to compile, the execute won't be created or will remain the 17 | last-compiled version. Adjust your code to resolve compiler errors and try again. 18 | 19 | ``` shell 20 | $ ./make 21 | $ ./compiled 22 | ``` 23 | 24 | ## Project TODO List: 25 | - [x] Complete `Pointer` constructor 26 | - [x] Complete `Pointer` `operator==` 27 | - [x] Complete `Pointer` destructor 28 | - [x] Complete `PtrDetails` class 29 | -------------------------------------------------------------------------------- /gc_details.h: -------------------------------------------------------------------------------- 1 | // This class defines an element that is stored 2 | // in the garbage collection information list. 3 | // 4 | template 5 | class PtrDetails 6 | { 7 | public: 8 | unsigned refcount; // current reference count 9 | T *memPtr; // pointer to allocated memory 10 | /* isArray is true if memPtr points 11 | to an allocated array. It is false 12 | otherwise. */ 13 | bool isArray; // true if pointing to array 14 | /* If memPtr is pointing to an allocated 15 | array, then arraySize contains its size */ 16 | unsigned arraySize; // size of array 17 | // Here, mPtr points to the allocated memory. 18 | // If this is an array, then size specifies 19 | // the size of the array. 20 | 21 | PtrDetails(void) 22 | { 23 | // TODO: Implement PtrDetails 24 | } 25 | }; 26 | // Overloading operator== allows two class objects to be compared. 27 | // This is needed by the STL list class. 28 | template 29 | bool operator==(const PtrDetails &ob1, 30 | const PtrDetails &ob2) 31 | { 32 | // TODO: Implement operator== 33 | } 34 | -------------------------------------------------------------------------------- /gc_iterator.h: -------------------------------------------------------------------------------- 1 | // Exception thrown when an attempt is made to 2 | // use an Iter that exceeds the range of the 3 | // underlying object. 4 | // 5 | class OutOfRangeExc 6 | { 7 | // Add functionality if needed by your application. 8 | }; 9 | 10 | 11 | // An iterator-like class for cycling through arrays 12 | // that are pointed to by GCPtrs. Iter pointers 13 | // ** do not ** participate in or affect garbage 14 | // collection. Thus, an Iter pointing to 15 | // some object does not prevent that object 16 | // from being recycled. 17 | // 18 | template 19 | class Iter 20 | { 21 | T *ptr; 22 | // current pointer value 23 | T *end; 24 | // points to element one past end 25 | 26 | T *begin; // points to start of allocated array 27 | unsigned length; // length of sequence 28 | public: 29 | Iter() 30 | { 31 | ptr = end = begin = NULL; 32 | length = 0; 33 | } 34 | Iter(T *p, T *first, T *last) 35 | { 36 | ptr = p; 37 | end = last; 38 | begin = first; 39 | length = last - first; 40 | } 41 | // Return length of sequence to which this 42 | // Iter points. 43 | unsigned size() { return length; } 44 | // Return value pointed to by ptr. 45 | // Do not allow out-of-bounds access. 46 | T &operator*() 47 | { 48 | if ((ptr >= end) || (ptr < begin)) 49 | throw OutOfRangeExc(); 50 | return *ptr; 51 | } 52 | // Return address contained in ptr. 53 | // Do not allow out-of-bounds access. 54 | T *operator->() 55 | { 56 | if ((ptr >= end) || (ptr < begin)) 57 | throw OutOfRangeExc(); 58 | return ptr; 59 | } 60 | // Prefix ++. 61 | Iter operator++() 62 | { 63 | ptr++; 64 | return *this; 65 | } 66 | // Prefix --. 67 | Iter operator--() 68 | { 69 | ptr--; 70 | return *this; 71 | } 72 | // Postfix ++. 73 | Iter operator++(int notused) 74 | { 75 | T *tmp = ptr; 76 | ptr++; 77 | return Iter(tmp, begin, end); 78 | } 79 | // Postfix --. 80 | Iter operator--(int notused) 81 | { 82 | T *tmp = ptr; 83 | ptr--; 84 | return Iter(tmp, begin, end); 85 | } 86 | // Return a reference to the object at the 87 | // specified index. Do not allow out-of-bounds 88 | // access. 89 | T &operator[](int i) 90 | { 91 | if ((i < 0) || (i >= (end - begin))) 92 | throw OutOfRangeExc(); 93 | return ptr[i]; 94 | } 95 | // Define the relational operators. 96 | bool operator==(Iter op2) 97 | { 98 | return ptr == op2.ptr; 99 | } 100 | bool operator!=(Iter op2) 101 | { 102 | return ptr != op2.ptr; 103 | } 104 | bool operator<(Iter op2) 105 | { 106 | return ptr < op2.ptr; 107 | } 108 | bool operator<=(Iter op2) 109 | { 110 | return ptr <= op2.ptr; 111 | } 112 | bool operator>(Iter op2) 113 | { 114 | return ptr > op2.ptr; 115 | } 116 | bool operator>=(Iter op2) 117 | { 118 | return ptr >= op2.ptr; 119 | } 120 | // Subtract an integer from an Iter. 121 | Iter operator-(int n) 122 | { 123 | ptr -= n; 124 | return *this; 125 | } 126 | // Add an integer to an Iter. 127 | Iter operator+(int n) 128 | { 129 | ptr += n; 130 | return *this; 131 | } 132 | // Return number of elements between two Iters. 133 | int operator-(Iter &itr2) 134 | { 135 | return ptr - itr2.ptr; 136 | } 137 | }; 138 | -------------------------------------------------------------------------------- /gc_pointer.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "gc_details.h" 6 | #include "gc_iterator.h" 7 | /* 8 | Pointer implements a pointer type that uses 9 | garbage collection to release unused memory. 10 | A Pointer must only be used to point to memory 11 | that was dynamically allocated using new. 12 | When used to refer to an allocated array, 13 | specify the array size. 14 | */ 15 | template 16 | class Pointer{ 17 | private: 18 | // refContainer maintains the garbage collection list. 19 | static std::list > refContainer; 20 | // addr points to the allocated memory to which 21 | // this Pointer pointer currently points. 22 | T *addr; 23 | /* isArray is true if this Pointer points 24 | to an allocated array. It is false 25 | otherwise. 26 | */ 27 | bool isArray; 28 | // true if pointing to array 29 | // If this Pointer is pointing to an allocated 30 | // array, then arraySize contains its size. 31 | unsigned arraySize; // size of the array 32 | static bool first; // true when first Pointer is created 33 | // Return an iterator to pointer details in refContainer. 34 | typename std::list >::iterator findPtrInfo(T *ptr); 35 | public: 36 | // Define an iterator type for Pointer. 37 | typedef Iter GCiterator; 38 | // Empty constructor 39 | // NOTE: templates aren't able to have prototypes with default arguments 40 | // this is why constructor is designed like this: 41 | Pointer(){ 42 | Pointer(NULL); 43 | } 44 | Pointer(T*); 45 | // Copy constructor. 46 | Pointer(const Pointer &); 47 | // Destructor for Pointer. 48 | ~Pointer(); 49 | // Collect garbage. Returns true if at least 50 | // one object was freed. 51 | static bool collect(); 52 | // Overload assignment of pointer to Pointer. 53 | T *operator=(T *t); 54 | // Overload assignment of Pointer to Pointer. 55 | Pointer &operator=(Pointer &rv); 56 | // Return a reference to the object pointed 57 | // to by this Pointer. 58 | T &operator*(){ 59 | return *addr; 60 | } 61 | // Return the address being pointed to. 62 | T *operator->() { return addr; } 63 | // Return a reference to the object at the 64 | // index specified by i. 65 | T &operator[](int i){ return addr[i];} 66 | // Conversion function to T *. 67 | operator T *() { return addr; } 68 | // Return an Iter to the start of the allocated memory. 69 | Iter begin(){ 70 | int _size; 71 | if (isArray) 72 | _size = arraySize; 73 | else 74 | _size = 1; 75 | return Iter(addr, addr, addr + _size); 76 | } 77 | // Return an Iter to one past the end of an allocated array. 78 | Iter end(){ 79 | int _size; 80 | if (isArray) 81 | _size = arraySize; 82 | else 83 | _size = 1; 84 | return Iter(addr + _size, addr, addr + _size); 85 | } 86 | // Return the size of refContainer for this type of Pointer. 87 | static int refContainerSize() { return refContainer.size(); } 88 | // A utility function that displays refContainer. 89 | static void showlist(); 90 | // Clear refContainer when program exits. 91 | static void shutdown(); 92 | }; 93 | 94 | // STATIC INITIALIZATION 95 | // Creates storage for the static variables 96 | template 97 | std::list > Pointer::refContainer; 98 | template 99 | bool Pointer::first = true; 100 | 101 | // Constructor for both initialized and uninitialized objects. -> see class interface 102 | template 103 | Pointer::Pointer(T *t){ 104 | // Register shutdown() as an exit function. 105 | if (first) 106 | atexit(shutdown); 107 | first = false; 108 | 109 | // TODO: Implement Pointer constructor 110 | // Lab: Smart Pointer Project Lab 111 | 112 | } 113 | // Copy constructor. 114 | template< class T, int size> 115 | Pointer::Pointer(const Pointer &ob){ 116 | 117 | // TODO: Implement Pointer constructor 118 | // Lab: Smart Pointer Project Lab 119 | 120 | } 121 | 122 | // Destructor for Pointer. 123 | template 124 | Pointer::~Pointer(){ 125 | 126 | // TODO: Implement Pointer destructor 127 | // Lab: New and Delete Project Lab 128 | } 129 | 130 | // Collect garbage. Returns true if at least 131 | // one object was freed. 132 | template 133 | bool Pointer::collect(){ 134 | 135 | // TODO: Implement collect function 136 | // LAB: New and Delete Project Lab 137 | // Note: collect() will be called in the destructor 138 | return false; 139 | } 140 | 141 | // Overload assignment of pointer to Pointer. 142 | template 143 | T *Pointer::operator=(T *t){ 144 | 145 | // TODO: Implement operator== 146 | // LAB: Smart Pointer Project Lab 147 | 148 | } 149 | // Overload assignment of Pointer to Pointer. 150 | template 151 | Pointer &Pointer::operator=(Pointer &rv){ 152 | 153 | // TODO: Implement operator== 154 | // LAB: Smart Pointer Project Lab 155 | 156 | } 157 | 158 | // A utility function that displays refContainer. 159 | template 160 | void Pointer::showlist(){ 161 | typename std::list >::iterator p; 162 | std::cout << "refContainer<" << typeid(T).name() << ", " << size << ">:\n"; 163 | std::cout << "memPtr refcount value\n "; 164 | if (refContainer.begin() == refContainer.end()) 165 | { 166 | std::cout << " Container is empty!\n\n "; 167 | } 168 | for (p = refContainer.begin(); p != refContainer.end(); p++) 169 | { 170 | std::cout << "[" << (void *)p->memPtr << "]" 171 | << " " << p->refcount << " "; 172 | if (p->memPtr) 173 | std::cout << " " << *p->memPtr; 174 | else 175 | std::cout << "---"; 176 | std::cout << std::endl; 177 | } 178 | std::cout << std::endl; 179 | } 180 | // Find a pointer in refContainer. 181 | template 182 | typename std::list >::iterator 183 | Pointer::findPtrInfo(T *ptr){ 184 | typename std::list >::iterator p; 185 | // Find ptr in refContainer. 186 | for (p = refContainer.begin(); p != refContainer.end(); p++) 187 | if (p->memPtr == ptr) 188 | return p; 189 | return p; 190 | } 191 | // Clear refContainer when program exits. 192 | template 193 | void Pointer::shutdown(){ 194 | if (refContainerSize() == 0) 195 | return; // list is empty 196 | typename std::list >::iterator p; 197 | for (p = refContainer.begin(); p != refContainer.end(); p++) 198 | { 199 | // Set all reference counts to zero 200 | p->refcount = 0; 201 | } 202 | collect(); 203 | } 204 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "gc_pointer.h" 2 | #include "LeakTester.h" 3 | 4 | int main() 5 | { 6 | Pointer p = new int(19); 7 | p = new int(21); 8 | p = new int(28); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /make: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | g++ -std=c++1y -Wall -o compiled main.cpp 4 | --------------------------------------------------------------------------------