久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

    • <bdo id='ZoP9A'></bdo><ul id='ZoP9A'></ul>

    <i id='ZoP9A'><tr id='ZoP9A'><dt id='ZoP9A'><q id='ZoP9A'><span id='ZoP9A'><b id='ZoP9A'><form id='ZoP9A'><ins id='ZoP9A'></ins><ul id='ZoP9A'></ul><sub id='ZoP9A'></sub></form><legend id='ZoP9A'></legend><bdo id='ZoP9A'><pre id='ZoP9A'><center id='ZoP9A'></center></pre></bdo></b><th id='ZoP9A'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='ZoP9A'><tfoot id='ZoP9A'></tfoot><dl id='ZoP9A'><fieldset id='ZoP9A'></fieldset></dl></div>

    <small id='ZoP9A'></small><noframes id='ZoP9A'>

    1. <tfoot id='ZoP9A'></tfoot>

      <legend id='ZoP9A'><style id='ZoP9A'><dir id='ZoP9A'><q id='ZoP9A'></q></dir></style></legend>
      1. 批評(píng)我的非侵入式堆調(diào)試器

        Critique my non-intrusive heap debugger(批評(píng)我的非侵入式堆調(diào)試器)

            <tbody id='7Nsuu'></tbody>
            <bdo id='7Nsuu'></bdo><ul id='7Nsuu'></ul>

            <legend id='7Nsuu'><style id='7Nsuu'><dir id='7Nsuu'><q id='7Nsuu'></q></dir></style></legend>
              • <i id='7Nsuu'><tr id='7Nsuu'><dt id='7Nsuu'><q id='7Nsuu'><span id='7Nsuu'><b id='7Nsuu'><form id='7Nsuu'><ins id='7Nsuu'></ins><ul id='7Nsuu'></ul><sub id='7Nsuu'></sub></form><legend id='7Nsuu'></legend><bdo id='7Nsuu'><pre id='7Nsuu'><center id='7Nsuu'></center></pre></bdo></b><th id='7Nsuu'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='7Nsuu'><tfoot id='7Nsuu'></tfoot><dl id='7Nsuu'><fieldset id='7Nsuu'></fieldset></dl></div>
                1. <tfoot id='7Nsuu'></tfoot>

                  <small id='7Nsuu'></small><noframes id='7Nsuu'>

                2. 本文介紹了批評(píng)我的非侵入式堆調(diào)試器的處理方法,對(duì)大家解決問(wèn)題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧!

                  問(wèn)題描述

                  限時(shí)送ChatGPT賬號(hào)..

                  這是對(duì)昨天的批評(píng)我的堆調(diào)試器的后續(xù).按照 bitc 的建議,我現(xiàn)在將有關(guān)已分配塊的元數(shù)據(jù)保存在單獨(dú)的手寫哈希表中.

                  This is a follow-up to Critique my heap debugger from yesterday. As suggested by bitc, I now keep metadata about the allocated blocks in a separate handwritten hashtable.

                  堆調(diào)試器現(xiàn)在檢測(cè)以下類型的錯(cuò)誤:

                  The heap debugger now detects the following kinds of errors:

                  1. 內(nèi)存泄漏(現(xiàn)在有更詳細(xì)的調(diào)試輸出)
                  2. 傳遞給 delete 的非法指針(也處理雙重刪除)
                  3. 錯(cuò)誤的刪除形式(數(shù)組與非數(shù)組)
                  4. 緩沖區(qū)溢出
                  5. 緩沖區(qū)下溢

                  歡迎討論并提前致謝!

                  #include <cstdio>
                  #include <cstdlib>
                  #include <cstring>
                  #include <new>
                  
                  namespace
                  {
                      // I don't want to #include <algorithm> for a single function template :)
                      template <typename T>
                      void my_swap(T& x, T& y)
                      {
                          T z(x);
                          x = y;
                          y = z;
                      }
                  
                      typedef unsigned char byte;
                  
                      const byte CANARY[] = {0x5A, 0xFE, 0x6A, 0x8D,
                                             0x5A, 0xFE, 0x6A, 0x8D,
                                             0x5A, 0xFE, 0x6A, 0x8D,
                                             0x5A, 0xFE, 0x6A, 0x8D};
                  
                      bool canary_dead(const byte* cage)
                      {
                          bool dead = memcmp(cage, CANARY, sizeof CANARY);
                          if (dead)
                          {
                              for (size_t i = 0; i < sizeof CANARY; ++i)
                              {
                                  byte b = cage[i];
                                  printf(b == CANARY[i] ? "__ " : "%2X ", b);
                              }
                              putchar('
                  ');
                          }
                          return dead;
                      }
                  
                      enum kind_of_memory {AVAILABLE, TOMBSTONE, NON_ARRAY_MEMORY, ARRAY_MEMORY};
                  
                      const char* kind_string[] = {0, 0, "non-array memory", "    array memory"};
                  
                      struct metadata
                      {
                          byte* address;
                          size_t size;
                          kind_of_memory kind;
                  
                          bool in_use() const
                          {
                              return kind & 2;
                          }
                  
                          void print() const
                          {
                              printf("%s at %p (%d bytes)
                  ", kind_string[kind], address, size);
                          }
                  
                          bool must_keep_searching_for(void* address)
                          {
                              return kind == TOMBSTONE || (in_use() && address != this->address);
                          }
                  
                          bool canaries_alive() const
                          {
                              bool alive = true;
                              if (canary_dead(address - sizeof CANARY))
                              {
                                  printf("ERROR:    buffer underflow at %p
                  ", address);
                                  alive = false;
                              }
                              if (canary_dead(address + size))
                              {
                                  printf("ERROR:     buffer overflow at %p
                  ", address);
                                  alive = false;
                              }
                              return alive;
                          }
                      };
                  
                      const size_t MINIMUM_CAPACITY = 11;
                  
                      class hashtable
                      {
                          metadata* data;
                          size_t used;
                          size_t capacity;
                          size_t tombstones;
                  
                      public:
                  
                          size_t size() const
                          {
                              return used - tombstones;
                          }
                  
                          void print() const
                          {
                              for (size_t i = 0; i < capacity; ++i)
                              {
                                  if (data[i].in_use())
                                  {
                                      printf(":( leaked ");
                                      data[i].print();
                                  }
                              }
                          }
                  
                          hashtable()
                          {
                              used = 0;
                              capacity = MINIMUM_CAPACITY;
                              data = static_cast<metadata*>(calloc(capacity, sizeof(metadata)));
                              tombstones = 0;
                          }
                  
                          ~hashtable()
                          {
                              free(data);
                          }
                  
                          hashtable(const hashtable& that)
                          {
                              used = 0;
                              capacity = 3 * that.size() | 1;
                              if (capacity < MINIMUM_CAPACITY) capacity = MINIMUM_CAPACITY;
                              data = static_cast<metadata*>(calloc(capacity, sizeof(metadata)));
                              tombstones = 0;
                  
                              for (size_t i = 0; i < that.capacity; ++i)
                              {
                                  if (that.data[i].in_use())
                                  {
                                      insert_unsafe(that.data[i]);
                                  }
                              }
                          }
                  
                          hashtable& operator=(hashtable copy)
                          {
                              swap(copy);
                              return *this;
                          }
                  
                          void swap(hashtable& that)
                          {
                              my_swap(data, that.data);
                              my_swap(used, that.used);
                              my_swap(capacity, that.capacity);
                              my_swap(tombstones, that.tombstones);
                          }
                  
                          void insert_unsafe(const metadata& x)
                          {
                              *find(x.address) = x;
                              ++used;
                          }
                  
                          void insert(const metadata& x)
                          {
                              if (2 * used >= capacity)
                              {
                                  hashtable copy(*this);
                                  swap(copy);
                              }
                              insert_unsafe(x);
                          }
                  
                          metadata* find(void* address)
                          {
                              size_t index = reinterpret_cast<size_t>(address) % capacity;
                              while (data[index].must_keep_searching_for(address))
                              {
                                  ++index;
                                  if (index == capacity) index = 0;
                              }
                              return &data[index];
                          }
                  
                          void erase(metadata* it)
                          {
                              it->kind = TOMBSTONE;
                              ++tombstones;
                          }
                      } the_hashset;
                  
                      struct heap_debugger
                      {
                          heap_debugger()
                          {
                              puts("heap debugger started");
                          }
                  
                          ~heap_debugger()
                          {
                              the_hashset.print();
                              puts("heap debugger shutting down");
                          }
                      } the_heap_debugger;
                  
                      void* allocate(size_t size, kind_of_memory kind) throw (std::bad_alloc)
                      {
                          byte* raw = static_cast<byte*>(malloc(size + 2 * sizeof CANARY));
                          if (raw == 0) throw std::bad_alloc();
                  
                          memcpy(raw, CANARY, sizeof CANARY);
                          byte* payload = raw + sizeof CANARY;
                          memcpy(payload + size, CANARY, sizeof CANARY);
                  
                          metadata md = {payload, size, kind};
                          the_hashset.insert(md);
                          printf("allocated ");
                          md.print();
                          return payload;
                      }
                  
                      void release(void* payload, kind_of_memory kind) throw ()
                      {
                          if (payload == 0) return;
                  
                          metadata* p = the_hashset.find(payload);
                  
                          if (!p->in_use())
                          {
                              printf("ERROR:   no dynamic memory at %p
                  ", payload);
                          }
                          else if (p->kind != kind)
                          {
                              printf("ERROR:wrong form of delete at %p
                  ", payload);
                          }
                          else if (p->canaries_alive())
                          {
                              printf("releasing ");
                              p->print();
                              free(static_cast<byte*>(payload) - sizeof CANARY);
                              the_hashset.erase(p);
                          }
                      }
                  }
                  
                  void* operator new(size_t size) throw (std::bad_alloc)
                  {
                      return allocate(size, NON_ARRAY_MEMORY);
                  }
                  
                  void* operator new[](size_t size) throw (std::bad_alloc)
                  {
                      return allocate(size, ARRAY_MEMORY);
                  }
                  
                  void operator delete(void* payload) throw ()
                  {
                      release(payload, NON_ARRAY_MEMORY);
                  }
                  
                  void operator delete[](void* payload) throw ()
                  {
                      release(payload, ARRAY_MEMORY);
                  }
                  
                  int main()
                  {
                      int* p = new int[1];
                      delete p;   // wrong form of delete
                      delete[] p; // ok
                      delete p;   // no dynamic memory (double delete)
                  
                      p = new int[1];
                      p[-1] = 0xcafebabe;
                      p[+1] = 0x12345678;
                      delete[] p; // underflow and overflow prevent release
                                  // p is not released, hence leak
                  }
                  

                  推薦答案

                  非常好,確實(shí).您的金絲雀實(shí)際上可以揭示一些真實(shí)的上溢/下溢情況(盡管不是馬修指出的所有情況).

                  Very nice, indeed. Your canaries could actually reveal some real cases of overflow/underflow (though not all of them as Matthieu pointed out).

                  還有什么.您可能會(huì)遇到多線程應(yīng)用程序的一些問(wèn)題.也許可以保護(hù)哈希表免受并發(fā)訪問(wèn)?

                  What more. You might run into some problems with a multi-threaded application. Perhaps protect the hashtable from concurrent access?

                  既然您記錄了每個(gè)分配和解除分配,您可以(如果愿意)提供有關(guān)正在測(cè)試的程序的更多信息.了解任何給定時(shí)間的總分配數(shù)和平均分配數(shù)可能會(huì)很有趣?分配的總字節(jié)數(shù)、最大字節(jié)數(shù)、最小字節(jié)數(shù)和平均字節(jié)數(shù),以及分配的平均壽命.

                  Now that you log every allocation and deallocation, you can (if you like) provide more information about the program being tested. It might be interesting to know the total and average number of allocations at any given time? The total, max, min and average bytes allocated, and the average lifespan of allocations.

                  如果你想比較不同的線程,至少在 Pthreads 中你可以用 pthread_self() 來(lái)識(shí)別它們.這個(gè)堆調(diào)試器可以成為一個(gè)非常有用的分析工具.

                  If you want to compare different threads, at least with Pthreads you can identify them with pthread_self(). This heap debugger could become a quite useful analysis tool.

                  這篇關(guān)于批評(píng)我的非侵入式堆調(diào)試器的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

                  【網(wǎng)站聲明】本站部分內(nèi)容來(lái)源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問(wèn)題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!

                  相關(guān)文檔推薦

                  Why do two functions have the same address?(為什么兩個(gè)函數(shù)的地址相同?)
                  Why the initializer of std::function has to be CopyConstructible?(為什么 std::function 的初始化程序必須是可復(fù)制構(gòu)造的?)
                  mixing templates with polymorphism(混合模板與多態(tài)性)
                  When should I use the keyword quot;typenamequot; when using templates(我什么時(shí)候應(yīng)該使用關(guān)鍵字“typename?使用模板時(shí))
                  Dependent name resolution amp; namespace std / Standard Library(依賴名稱解析命名空間 std/標(biāo)準(zhǔn)庫(kù))
                  gcc can compile a variadic template while clang cannot(gcc 可以編譯可變參數(shù)模板,而 clang 不能)
                  <legend id='pDJ09'><style id='pDJ09'><dir id='pDJ09'><q id='pDJ09'></q></dir></style></legend>
                    <bdo id='pDJ09'></bdo><ul id='pDJ09'></ul>

                    <small id='pDJ09'></small><noframes id='pDJ09'>

                        <i id='pDJ09'><tr id='pDJ09'><dt id='pDJ09'><q id='pDJ09'><span id='pDJ09'><b id='pDJ09'><form id='pDJ09'><ins id='pDJ09'></ins><ul id='pDJ09'></ul><sub id='pDJ09'></sub></form><legend id='pDJ09'></legend><bdo id='pDJ09'><pre id='pDJ09'><center id='pDJ09'></center></pre></bdo></b><th id='pDJ09'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='pDJ09'><tfoot id='pDJ09'></tfoot><dl id='pDJ09'><fieldset id='pDJ09'></fieldset></dl></div>
                          <tbody id='pDJ09'></tbody>
                        • <tfoot id='pDJ09'></tfoot>

                          1. 主站蜘蛛池模板: 特级毛片 | 免费黄视频网站 | 日本久久黄色 | 九九热在线视频观看这里只有精品 | 高清视频一区二区三区 | 欧美一区二区三区在线视频 | 操视频网站 | 91精品国产91久久久久久丝袜 | 亚洲成年人免费网站 | 在线观看国产网站 | 91视频在线观看免费 | 久久免费精彩视频 | 亚洲一区二区三区视频 | 在线免费观看亚洲 | 国产精品成人一区 | 人人看人人干 | 欧美精品在欧美一区二区少妇 | 青春草在线 | 久久美国| 午夜成人免费视频 | 午夜视频网站 | 国产精品一区二区三区在线播放 | 亚洲色图50p| 国产精品毛片av一区 | 麻豆国产一区二区三区四区 | 日韩最新网址 | 亚洲成人毛片 | 欧美一区二区三区久久精品 | 国产精品国产三级国产aⅴ入口 | 精品成人一区 | 日韩激情在线 | 久久久久久国产精品免费免费 | 99免费在线视频 | 三区四区在线观看 | 日韩精品在线播放 | 在线观看中文字幕 | 亚洲乱码国产乱码精品精98午夜 | 影音先锋亚洲资源 | www.四虎.com| 中文成人在线 | 一区二区三区在线 |