分段错误错误c ++动态数组

时间:2015-11-12 04:16:53

标签: c++ segmentation-fault

所以我正在编写一个ArrayList类,它在内部使用一个数组和一些函数来维护容量(即收缩和增长函数)。我收到分段错误错误,我知道这意味着我正在尝试访问我无法访问的内存,这可能发生在我的重载[]运算符中,但我似乎无法弄清楚是什么导致了这个问题。 任何帮助将不胜感激!

ArrayList.cpp

#include "ArrayList.h"
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int& ArrayList::operator[](unsigned int i){
    try{
        cout << "[] called: i  = " << i << ".........return val = " << foo[i] << endl ; 
        if(i >= numElements)
            throw 1;
        return foo[i];
    }
    catch(int e){
        cout << "An error has occured. Error code " << e;
        switch(e) {
            case 1:{
                            cout << ". You may be trying to access an index that doesn't currently exist in the arraylist!" << endl;
                            break; //1 = IndexOutofBoundException
            }   
        }
    }
}
int ArrayList::size(){
    return numElements;
}
void ArrayList::shrink(){
    int* bar = new int[capacity/2]; //temp array to hold values while I decrease the size
    for(int i = 0; i < capacity/2; i++){
        bar[i] = foo[i];    
    }
    delete foo;
    foo = bar;
    capacity /=2;
}

void ArrayList::grow(){
    int* bar = new int[capacity*2]; //temp array to hold values while I increase the size
    for(int i = 0; i < capacity; i++){
        bar[i] = foo[i];
    }
    for(int i = capacity; i < capacity*2;i++){
        bar[i] = 0;
    }
    delete foo;
    foo = bar;
    capacity *=2;
}

void ArrayList::push_back(int m){
    if(numElements == capacity) //full, double foo
        grow();
    foo[numElements] = m;
    numElements++;
}

void ArrayList::erase(int m){
    bool notFound = true;   
    int i = 0;
    while(notFound){
        if(foo[i] == m){
            notFound = false;    //Ha! Found you!
            for(int j = i; j < capacity; j++){
                foo[j] = foo[j+1]; //moves everything to right of m one spot left
                numElements--;
            }
        }
        else
            i++; //keep looking
    }
    if(numElements*2<capacity)
        shrink();
}

string ArrayList::toString(){
    stringstream sobj;
    string x;
    sobj << "[";
    for(int i = 0; i < numElements; i++){
        if(i == numElements-1) //last iteration, avoids output displaying [1,2,3,4,]
            sobj << foo[i];
        else
            sobj << foo[i] << ",";
    }
    sobj << "]";
    sobj >> x;
    return x;
}

ArrayList::ArrayList(){
    capacity = 1;   
    numElements = 0;
    foo = new int[1];
    foo[0] = 0;
}

ArrayList::~ArrayList(){
    delete foo;
    cout << "Destructor called" << endl;
}

ArrayList.h

#ifndef _ARRAYLIST_H_
#define _ARRAYLIST_H_
#include <string>
class ArrayList
{
 public:
    ArrayList();
    ~ArrayList();

    int& operator[](unsigned int i);

    void push_back(int m); 
    void erase(int m);
    std::string toString();
    int size();

 private: 
  void shrink();
    void grow();

 private:
  int capacity, numElements;
    int* foo;
};

#endif

Test.cpp的

#include "ArrayList.h"
#include <iostream>
using namespace std;

int main(int argc,char *argv[])
{
    ArrayList arr;

    for (int i=1;i<=50;i++)
    {
        arr.push_back(i);
    }

    cout << "Should contain numbers 1..50, is ";

    cout << arr.toString() << endl;

    for (int i=arr.size()-1;i>=1;i--)
    {
        arr.erase(arr[i]);
    }   

    cout << "Should contain only 1, is ";
    cout << arr.toString() << endl;

    arr.erase(arr[0]);

    for (int i=2;i<=50;i++)
    {
        if (i<=2)
            arr.push_back(i);
        else
        {
            int j=0;
            while ((j<arr.size()) && (i%arr[j]!=0))
                j++;

            if (j==arr.size())
            {
                arr.push_back(i);
            }
        }
    }

    cout << "Prime numbers between 1 and 50 are: " << arr.toString() << endl;

}

1 个答案:

答案 0 :(得分:3)

您在函数ArrayList::erase()中有错误。

void ArrayList::erase(int m){
    bool notFound = true;   
    int i = 0;
    while(notFound){
        if(foo[i] == m){
            notFound = false;    //Ha! Found you!
            for(int j = i; j < capacity; j++){
                foo[j] = foo[j+1]; //moves everything to right of m one spot left

                //========================================
                // Problem.
                // This is in the wrong place.
                // It needs to be outside the for loop.
                //========================================
                numElements--;
            }
        }
        else
            i++; //keep looking
    }
    if(numElements*2<capacity)
        shrink();
}

固定功能:

void ArrayList::erase(int m){
    bool notFound = true;   
    int i = 0;
    while(notFound){
        if(foo[i] == m){
            notFound = false;    //Ha! Found you!
            for(int j = i; j < capacity; j++){
                foo[j] = foo[j+1]; //moves everything to right of m one spot left
            }

            //========================================
            // It needs to be outside the for loop.
            //========================================
            numElements--;
        }
        else
            i++; //keep looking
    }
    if(numElements*2<capacity)
        shrink();
}

顺便说一句,通过在删除项目后立即添加一行来打印数组内容,我能够快速识别问题。

for (int i=arr.size()-1;i>=1;i--)
{
   arr.erase(arr[i]);
   cout << arr.toString() << endl;
}   

该功能的更强大版本将是:

void ArrayList::erase(int m){    
   for ( int i = 0; i < numElements; ++i )
   {
      if(foo[i] == m){

         // You need to move only the number of
         // items of the array that have user set
         // numbers.
         for(int j = i; j < numElements-1; j++){
            foo[j] = foo[j+1];
         }

         // This is strictly not necessary but is
         // in the spirit of rest of your code where
         // you initialize to zero all members that have
         // not been explicitly set by the user.
         foo[numElements-1] = 0;

         numElements--;
         break;
      }
   }

   if(numElements*2 < capacity)
      shrink();
}