2016-02-05 121 views
1

我已經看過這個問題,但我沒有真正收到一個好的答案,所以我想我會問這裏。Visual Studio C++「ProjectName.exe引發了一個斷點」和其他問題

我正在C++中處理一些涉及內存操作的項目(分配動態字符數組,並將內存地址和全部對象放入這些使用放置位置的數組中)。

每當我在Visual Studio中調試程序時,我都會遇到一個非常令人沮喪的問題:彈出一條消息,通常會提示「ProjectName.exe已觸發斷點」。有時會說「類似於」2中引發的異常0x0FFD66CB(ucrtbased.dll) - Kennel.exe:0xC0000005:訪問衝突讀取位置0xFFFFFFF5。「

下面是相關類的代碼

Cat.h

#ifndef CAT_H 
#define CAT_H 

#include <string> 
#include "Kennel.h" 

using std::string; 

class Cat { 
private: 
    static Kennel catKennel; 
    int _id; 
    string _name; 

    Cat(int i, const string& nm) : _name(nm) { // Note initializer list 
     _id = i; 
    } 

    void* operator new(size_t size){ 
     return catKennel.allocate(); 
    } 
public: 
    static Cat* create(int id, const string& name) { // Factory method 
     return new Cat(id, name); 
    } 

    void operator delete(void* loc) { 
     catKennel.deallocate(loc); 
    } 
}; 

Kennel Cat::catKennel(sizeof(Cat), 5); 

#endif 

Kennel.h

#ifndef KENNEL_H 
#define KENNEL_H 

#include <cstddef> 
#include <cassert> 
#include <iostream> 
#include <new> 

class Kennel { 
private: 
    static const size_t _BUCKET_COUNT = 10; 
    const size_t _BUCKET_SIZE; 
    const size_t _ELEM_SIZE; 
    char* buckets[_BUCKET_COUNT]; 
    //char** buckets; 
    char* availableBlock; 
public: 
    Kennel(size_t elemSize, size_t bucketSize = 5); 
    ~Kennel(); 
    void* allocate(); // Get a pointer inside a pre-allocated block for a new object 
    void deallocate(void*); // Free an object's slot (push the address on the "free list") 
}; 

#endif 

Kennel.cpp

#include "Kennel.h" 

Kennel::Kennel(size_t elemSize, size_t bucketSize) : _ELEM_SIZE(elemSize), _BUCKET_SIZE(bucketSize) { 
    //Set each element in buckets to nullptr. 
    for (int i = 0; i < _BUCKET_COUNT; i++) 
     buckets[i] = nullptr; 
} 

Kennel::~Kennel() { 
    //Delete each character array in buckets. 
    for (int i = 0; i < _BUCKET_COUNT; i++) { 
     if (buckets[i] != nullptr) 
      delete[] buckets[i]; 
    } 
} 

void* Kennel::allocate() { 
    //If there is no available bucket: create a new one. 
    if (availableBlock == nullptr) { 
     //Find next array index in buckets array where we can create a new bucket. 
     int nextNullBucketIndex = -1; 
     for (int i = 0; i < _BUCKET_COUNT; i++) { 
      if (buckets[i] == nullptr) { 
       nextNullBucketIndex = i; 
       break; 
      } 
     } 
     assert(nextNullBucketIndex > -1); //If there is no space to create another bucket: exit. 

     //Create a new bucket. 
     buckets[nextNullBucketIndex] = new char(_BUCKET_SIZE * _ELEM_SIZE); 
     availableBlock = buckets[nextNullBucketIndex]; 
     char* tempBlock = availableBlock; 

     //Put the address of the next block inside each block. 
     std::cout << "Bucket " << nextNullBucketIndex << ": "; 
     for (int i = 0; i < _BUCKET_SIZE - 1; i++) { 
      std::cout << static_cast<void*>(tempBlock) << ' '; 
      new (tempBlock) char*(tempBlock += _ELEM_SIZE); 
     } 
     std::cout << static_cast<void*>(tempBlock) << std::endl; 
     new (tempBlock) char*(nullptr); //The last block doesn't get an address, put nullptr in it. 
    } 

    char* tempAvailable = availableBlock; 
    availableBlock = *reinterpret_cast<char**>(availableBlock); 

    std::cout << "Returning: " << static_cast<void*>(tempAvailable) << std::endl; 
    return static_cast<void*>(tempAvailable); 
} 

void Kennel::deallocate(void* loc) { 
    new (loc) char*(availableBlock); //Store availableBlock's contained address in loc. 
    availableBlock = static_cast<char*>(loc); //Set availableBlock's contained address to be loc's address. 
} 

的問題每次都不同我跑我的編內存。以下是關於嘗試運行時遇到的更常見問題的一些信息。

它試圖執行Kennel.cpp線48時,在分配

std::cout << "Returning: " << static_cast<void*>(tempAvailable) << std::endl; 

它往往打破在我的主要功能有一行刪除目錄對象經常斷裂。

當它調用Kennel的解構器時,它有時會在程序結束時中斷。

等...

正如我所說的,這是看似隨意哪一行代碼會決定打破。另外,我幾乎可以確定問題出在Kennel類上,因爲我使用我的代碼使用我的朋友的Kennel.h和Kennel.cpp,它的工作完美無瑕。

任何幫助將不勝感激。

+1

如果您收到「ProjectName.exe觸發了斷點」,請檢查控制檯,並檢查可能位於其他窗口後面的對話框。當標準庫檢測到你做錯了什麼時,它通常會顯示一條消息,然後觸發一個斷點(當你不使用調試器時會發生崩潰)。 – immibis

回答

2
buckets[nextNullBucketIndex] = new char(_BUCKET_SIZE * _ELEM_SIZE); 

這隻分配一個char,而不是它們的數組。然後你繼續寫東西到你不擁有的內存中。 std::string也s那相同的記憶,然後你的堆被搞砸了。

+0

我正式是一個笨蛋。我做了這麼多事情,我只是忽略了每一篇文章。 –

相關問題