簡體   English   中英

new int []引發“訪問沖突”異常

[英]new int[] throws 'Access Violation' exception

我一直在研究自定義Vector類。 一切在Microsoft編譯器上都可以正常運行,但是當我在Borland上嘗試時,卻遇到了一個非常奇怪的錯誤。

Borland在insert函數中引發異常; 恰好在調用復制構造函數“ Vector temp(* this);”時

“ array_ = new int [rhs.size_];”

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

我認為,第一次調用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的源代碼以提高效率。

您(顯然) array_insert()內部調整array_大小。 這意味着您將始終在其分配的內存末尾寫入一個元素。

復制整個數組(兩次)會導致非常昂貴的插入。 您要達到什么目的是無法在std::vector

在您的insert函數中,您不會為新插入的項目分配內存,並且在第一次插入副本后,ctr嘗試讀取該行上未分配的內存,這將引發異常。 解決方案是首先分配更多的內存(這就是為什么容量用於典型的矢量實現)或在每個插入上增加分配的數組。 您必須在兩個解決方案上都實現重新分配,但是在第一個解決方案中,調用頻率會降低。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM