简体   繁体   English

new int []引发“访问冲突”异常

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

I've been working on custom Vector class. 我一直在研究自定义Vector类。 Everything works perfectly fine on Microsoft compiler, however when I try it on Borland I'm getting a really strange error. 一切在Microsoft编译器上都可以正常运行,但是当我在Borland上尝试时,却遇到了一个非常奇怪的错误。

Borland throws the exception inside the insert function; Borland在insert函数中引发异常; Exactly when calling the copy constructor "Vector temp(*this);" 恰好在调用复制构造函数“ Vector temp(* this);”时 at the

"array_ = new int[rhs.size_];" “ 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];
    }
}

and here is my copy constructor; 这是我的复制构造函数;

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];
    }
}

and finally this is the main(); 最后是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);

The strange thing is first insert call(a.insert(99, 3)) works fine, it crashes when it comes to the second call(a.insert(98, 0)) 奇怪的是,第一个插入调用(a.insert(99,3))正常工作,当涉及第二个调用(a.insert(98,0))时崩溃

Here's the full header file 这是完整的头文件

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

In my opinion, damage is done when you call the insert() for the first time. 我认为,第一次调用insert()造成损坏。 When you insert an element, you also have to increase the allocated bytes to your member array_ . 插入元素时,还必须增加分配给成员array_字节。 You are simply increasing the size_ , but what about increasing the size of actual array_ ? 您只是在增加size_ ,但是增加实际array_的大小呢?

For example, something like below is happening in your insert() : 例如,在您的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'

After calling, first insert your stack will be already corrupt. 调用后,首先插入您的堆栈将已损坏。 So 2nd time it's crashing. 所以第二次它崩溃了。 Just verify with according code changes. 只需验证相应的代码更改即可。

On side note, 在旁注,

  • I feel that you can write insert() , more optimized. 我觉得您可以编写更优化的insert() I don't feel need to copy the full Vector<> in temporary. 我觉得不需要临时复制完整的Vector<>
  • Also, try to allocate more number of bytes to array_ than actual need. 另外,尝试为array_分配比实际需要更多的字节数。 So that you don't have to reallocate many times 这样您就不必多次重新分配
  • Try seeing the source code of actual vector from STL for better efficiency. 尝试从STL查看实际vector的源代码以提高效率。

You are not (visibly) resizing array_ inside insert() . 您(显然) array_insert()内部调整array_大小。 This means that you will always write one element past the end of its allocated memory. 这意味着您将始终在其分配的内存末尾写入一个元素。

Copying the entire array (twice) makes for a very expensive insertion. 复制整个数组(两次)会导致非常昂贵的插入。 What are you trying to achieve that can't be done in std::vector ? 您要达到什么目的是无法在std::vector

In your insert function you don't allocate memory for the newly inserted item and after the first insert the copy ctr tries to read unallocated memory on the line it is throwing the exception. 在您的insert函数中,您不会为新插入的项目分配内存,并且在第一次插入副本后,ctr尝试读取该行上未分配的内存,这将引发异常。 The solution would be to allocate more memory initially (that's why capacity is used for typical vector implementations) or to increase the allocated array on every insert. 解决方案是首先分配更多的内存(这就是为什么容量用于典型的矢量实现)或在每个插入上增加分配的数组。 You have to implement the reallocation on both solutions but in the first one it will be called less often. 您必须在两个解决方案上都实现重新分配,但是在第一个解决方案中,调用频率会降低。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM