2011-04-17 108 views
0

我一直在處理自定義Vector類。一切工作完美罰款微軟編譯器,但是當我在Borland上嘗試它時,我得到一個非常奇怪的錯誤。new int []拋出'訪問衝突'異常

Borland在插入函數內拋出異常; 正確調用拷貝構造函數「Vector temp(* this);」在

「array_ = new int [rhs.size_];」 line

void Vector::insert(int value, unsigned position) throw(SubscriptError) 
{ 
    check_bounds(position); 
    Vector temp(*this); 
    int tmpSize= size_; 
    temp.size_++; 
    size_++; 
    for (unsigned int i=tmpSize; i > position; i--) 
    { 
     temp[i] = temp[i-1]; 
    } 
    temp[position] = value; 

    //array_= temp.array_; 
    for(unsigned int i = 0; i < size_; i++) 
    { 
     array_[i]= temp.array_[i]; 
    } 
} 

這裏是我的複製構造函數;

Vector::Vector(const Vector& rhs) 
{ 
    array_ = new int[rhs.size_]; 
    size_ = rhs.size_; 
    for(unsigned int i = 0; i < rhs.size_; i++) 
    { 
     array_[i] = rhs.array_[i]; 
    } 
} 

最後這是main();

std::cout << "push_back 5 integers:\n"; 
for (int i = 0; i < 5; i++) 
{ 
    a.push_back(i); 
    Print(a); 
} 

std::cout << "insert(99, 3):\n"; 
a.insert(99, 3); 
Print(a); 
std::cout << "insert(98, 0):\n"; 
a.insert(98, 0); 
Print(a); 
std::cout << "insert(97, 6):\n"; 
a.insert(97, 6); 
Print(a); 

奇怪的是第一次插入通話(a.insert(99,3))正常工作,當它涉及到第二個呼叫崩潰(a.insert(98,0))

下面是完整的頭文件

namespace CS170 
{ 
    class SubscriptError 
    { 
    public: 
     SubscriptError(int Subscript) : subscript_(Subscript) {}; 
     int GetSubscript(void) const { return subscript_; } 

    private: 
    int subscript_; 
    }; 

class Vector 
{ 
public: 

    static const int NO_INDEX = -1; 

    struct SortResult 
    { 
     unsigned compares; 
     unsigned swaps; 
    }; 

    // Default constructor 
    Vector(void); 

    // Destructor 
    ~Vector(); 

    // Copy constructor 
    Vector(const Vector& rhs); 

    // Constructor to create a Vector from an array 
    Vector(const int array[], unsigned size); 

    // Adds a node to the front of the list 
    void push_back(int value); 

    // Adds a node to the end of the list 
    void push_front(int value); 

    // Removes the last element. Does nothing if empty. 
    void pop_back(void); 

    // Removes the first element. Does nothing if empty. 
    void pop_front(void); 

    // Inserts a new node at the specified position. Causes an 
    // abort() if the position is invalid. (Calls check_bounds) 
    void insert(int value, unsigned position) throw(SubscriptError); 

    // Removes an element with the specified value (first occurrence) 
    void remove(int value); 

    // Deletes the underlying array and sets size_ to 0 
    void clear(void); 

    // Return true if the vector is empty, otherwise, false 
    bool empty(void) const; 

    // Assignment operator 
    Vector& operator=(const Vector& rhs); 

    // Concatenates a vector onto the end of this vector. 
    Vector& operator+=(const Vector& rhs); 

    // Concatenates two Vectors. 
    Vector operator+(const Vector& rhs) const; 

    // Subscript operators. 
    int operator[](unsigned index) const throw(SubscriptError); 
    int& operator[](unsigned index) throw(SubscriptError); 

    // Returns the number of elements in the vector. 
    unsigned size(void) const; 

    // Returns the size of the underlying array 
    unsigned capacity(void) const; 

    // The number of memory allocations that have occurred 
    unsigned allocations(void) const; 

    // This searches the vector using a binary search instead 
    // of a linear search. The data must be sorted. Returns 
    // the index. If not found, returns CS170::Vector::NO_INDEX. 
    // DO NOT SORT THE DATA IN THIS FUNCTION!!  
    int bsearch(int value) const; 

    // Sorts the elements using a selection sort. 
    // Returns the number of swaps/comparisons that occurred. 
    SortResult selection_sort(void); 

    // Sorts the elements using a bubble_sort. 
    // Returns the number of swaps/comparisons that occurred. 
    SortResult bubble_sort(void); 

    void swap(int &a, int& b); 

    void swapv(Vector &other); 

    void reverse(void); 

    bool operator==(const Vector& rhs) const; 

    void shrink_to_fit(void); 

private: 
    int *array_;  // The dynamically allocated array 
    unsigned size_;  // The number of elements in the array 
    unsigned capacity_; // The allocated size of the array 
    unsigned allocs_; // Number of allocations (resizes) 

    // Private methods... 
    void check_bounds(unsigned index) const throw(SubscriptError); 
    void grow(void); 

    // Other private methods... 
}; 

    }// namespace CS170 

     #endif // VECTOR_H 
+0

@Brian:爲什麼會出現rhs.size_'爲private的問題?一個類可以完全訪問其內部,所以你當然可以訪問你自己內部的另一個Vector對象的'size_'。 – Xeo 2011-04-17 06:48:30

+0

不要使用異常規範(函數頭中的'throw(SubscriptError)'),它們將從C++中移除。 – ybungalobill 2011-04-17 06:48:40

回答

2

您不是(可見地)調整大小array_裏面insert()。這意味着您將始終在其分配的內存末尾寫入一個元素。

複製整個數組(兩次)會導致非常昂貴的插入。你想在std::vector不能做什麼?

+1

看起來像作業「命名空間CS170」 – Vusak 2011-04-17 06:41:38

2

在我看來,當你調用insert()首次傷害已經造成。插入元素時,還必須將分配的字節數增加到您的成員array_。你只是增加size_,但增加實際的array_的大小呢?

例如,像下面是發生在你的insert()

int size = 5; 
int *p = new int[size]; 
// ... populate p[i] (i = 0 to i = size - 1) 
size ++; 
p[size - 1] = VALUE; // oops ... incremented 'size' but before that reallocate to 'p' 

呼叫後,首先插入你的籌碼將已經損壞。所以第二次它崩潰了。只需根據代碼更改進行驗證。

在旁註,

  • 我覺得你可以寫insert(),更優化。我不覺得需要臨時複製完整的Vector<>
  • 此外,嘗試分配更多的字節數array_比實際需要。所以,你不必重新分配多次
  • 嘗試看到從STL實際vector的源代碼,以便提高效率。
0

在你插入功能您沒有爲新插入的項目分配內存和第一插入後的副本CTR試圖在它拋出異常的行讀取未分配的內存。解決方法是最初分配更多的內存(這就是爲什麼容量用於典型的矢量實現)或增加每個插入的分配數組。您必須在兩種解決方案上實施重新分配,但在第一種解決方案中,它將不太經常調用。