c ++数组[]运算符抛出不起作用

c++ array [] operator throws not working

好的,所以我为我的 safeArray::operator[] 创建了一些 throws,但这些 throws 仅适用于某些数字——其他数字会导致程序因某种原因崩溃。

目前如果我有:

if (index < startingIndex)
    {
        try
        {
            throw 1;

        }
        catch (int &e)
        {
            printf("caught it\n"); throw;
        }
    }

throws 按预期工作并且不会使我的程序崩溃,但如果我包括:

if (index >= capacity)
    {
        try
        {
            throw 1;

        }
        catch (int &e)
        {
            printf("caught it\n"); throw;
        }
    }

当我包含这段代码以将 throws 添加到其余数字时,我的程序崩溃并显示 abort() 已被调用。据我所知,参数是正确的,所以我不确定它为什么会崩溃。

其余代码:

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

//To prevent those using g++ from trying to use a library
//they don't have
#ifndef __GNUC__
#include <conio.h>
#endif

using namespace std;

class SafeArray {


public:
    SafeArray();
    SafeArray(const int, const unsigned int);
    ~SafeArray();
    int& operator[](const int);
    friend string arrayToString(const SafeArray&);
    int getLowIndex();
    int getHighIndex();
    int length();
    void resize(const int, const unsigned int);


private:
    unsigned int capacity;
    int * arr;
    int startingIndex;
};

int SafeArray::getHighIndex(){
    int low = this->startingIndex;
    int high = this->capacity;
    int retval = low + high - 1;
    return retval;
}

int SafeArray::getLowIndex() {

    return startingIndex;
}

int SafeArray::length() {

    return capacity;
}

void SafeArray::resize(const int start, const unsigned int capacity1)
{
    int delta = startingIndex - start;
    size_t newSize = capacity1;
    int* newArr = new int[newSize];

    memcpy(newArr+delta, arr, capacity * sizeof(int));

    capacity = newSize;
    delete[] arr;
    this->startingIndex = start;
    this->capacity = capacity1;
    arr = newArr;
}



//This helps with testing, do not modify.
bool checkTest(string testName, string whatItShouldBe, string whatItIs) {

    if (whatItShouldBe == whatItIs) {
        cout << "Passed " << testName << endl;
        return true;
    }
    else {
        cout << "****** Failed test " << testName << " ****** " << endl << "     Object contained: " << whatItIs << endl << "     Output should have contained: " << whatItShouldBe << endl;
        return false;
    }
}

//This helps with testing, do not modify.
bool checkTest(string testName, int whatItShouldBe, int whatItIs) {

    if (whatItShouldBe == whatItIs) {
        cout << "Passed " << testName << endl;
        return true;
    }
    else {
        cout << "****** Failed test " << testName << " ****** " << endl << "     Object contained: " << whatItIs << endl << "     Output should have contained: " << whatItShouldBe << endl;
        return false;
    }
}

string arrayToString(const SafeArray& obj) {
    stringstream ss;

    for (unsigned int i = 0; i < obj.capacity; i++) {
        ss << obj.arr[i] << " ";
    };
    string str = ss.str();
    size_t found;
    found = str.find_last_not_of(" ");
    if (found != string::npos)
        str.erase(found + 1);
    else
        str.clear();            // str is all whitespace

    return str;
}

SafeArray::SafeArray(const int startingIndex, const unsigned int capacity) {
    this->arr = new int[capacity];   

    this->startingIndex = startingIndex;

    this->capacity = capacity;

}

SafeArray::~SafeArray() {
    delete[] arr;
}

int& SafeArray::operator[](int index) {
    if (index < startingIndex)
    {
        try
        {
            throw 1;

        }
        catch (int &e)
        {
            printf("caught it\n"); throw;
        }
    }


    return arr[index-startingIndex];
}

void safeArrayTests() {

    //Test constructor
    SafeArray a(0, 5);
    for (int i = 0; i < 5; i++) {
        a[i] = i + 20;
    };

    checkTest("safeArrayTests #1", "20 21 22 23 24", arrayToString(a));
    //Test methods
    checkTest("safeArrayTests #2", 0, a.getLowIndex());
    checkTest("safeArrayTests #3", 4, a.getHighIndex());
    checkTest("safeArrayTests #4", 5, a.length());
    //Test operator [] overload
    checkTest("safeArrayTests #5", 20, a[0]);
    checkTest("safeArrayTests #6", 24, a[4]);
    try {
        checkTest("safeArrayTests #7", 0, a[5]);
        cout << "Passed safeArayTests #7" << endl;
    }
    catch (int error) {
        cout << "Passed safeArayTests #7" << endl;
    }
    try {
        checkTest("safeArrayTests #8", 0, a[-1]);
        cout << "****** Failed test safeArayTests #8 ******.  An error should have been thrown, but wasn't." << endl;
    }
    catch (int error) {
        cout << "Passed safeArayTests #8" << endl;
    }

    //Test offsetting the array
    SafeArray b(5, 10);
    int i;
    for (i = 5; i < 15; i++) {
        b[i] = i + 100;
    };

    checkTest("safeArrayTests #9", "105 106 107 108 109 110 111 112 113 114", arrayToString(b));
    //Test methods
    checkTest("safeArrayTests #10", 5, b.getLowIndex());
    checkTest("safeArrayTests #11", 14, b.getHighIndex());
    checkTest("safeArrayTests #12", 10, b.length());
    //Test operator [] overload
    checkTest("safeArrayTests #13", 105, b[5]);
    checkTest("safeArrayTests #14", 114, b[14]);
    try {
        checkTest("safeArrayTests #15", 0, b[4]);
        cout << "****** Failed test safeArayTests #7 ******.  An error should have been thrown, but wasn't." << endl;
    }
    catch (int error) {
        cout << "Passed safeArayTests #15" << endl;
    }
    try {
        checkTest("safeArrayTests #16", 0, a[15]);
        cout << "****** Failed test safeArayTests #7 ******.  An error should have been thrown, but wasn't." << endl;
    }
    catch (int error) {
        cout << "Passed safeArayTests #16" << endl;
    }

    //Test resizing
    //Make sure the existing elements were untouched.
    b.resize(3, 15);
    checkTest("safeArrayTests #17", 3, b.getLowIndex());
    checkTest("safeArrayTests #18", 17, b.getHighIndex());
    checkTest("safeArrayTests #19", 15, b.length());
    checkTest("safeArrayTests #20", 105, b[5]);
    checkTest("safeArrayTests #21", 114, b[14]);
    //attempt to write to b[3] and b[17] without crashing
    b[3] = 1;
    b[17] = 2;
    checkTest("safeArrayTests #22", 1, b[3]);
    checkTest("safeArrayTests #23", 2, b[17]);
    try {
        b[2] = 666;
        cout << "****** Failed test safeArayTests #24 ******.  An error should have been thrown, but wasn't." << endl;
    }
    catch (int error) {
        cout << "Passed safeArayTests #24" << endl;
    }



    //Test resizing into negative
    b.resize(-4, 23);
    checkTest("safeArrayTests #25", 105, b[5]);
    checkTest("safeArrayTests #26", 114, b[14]);
    checkTest("safeArrayTests #27", 1, b[3]);
    checkTest("safeArrayTests #28", 2, b[17]);
    b[-4] = 1234;
    checkTest("safeArrayTests #29", 1234, b[-4]);


    //Test offsetting the array
    SafeArray c(-20, 4);
    for (i = -20; i < -16; i++) {
        c[i] = i - 10;
    };

    checkTest("safeArrayTests #30", "-30 -29 -28 -27", arrayToString(c));
    //Test methods
    checkTest("safeArrayTests #31", -20, c.getLowIndex());
    checkTest("safeArrayTests #32", -17, c.getHighIndex());
    checkTest("safeArrayTests #33", 4, c.length());
    //Test operator [] overload
    checkTest("safeArrayTests #34", -30, c[-20]);
    checkTest("safeArrayTests #35", -27, c[-17]);

    //Test resizing
    //Make sure the existing elements were untouched.
    c.resize(-21, 6);
    checkTest("safeArrayTests #36", -21, c.getLowIndex());
    checkTest("safeArrayTests #37", -16, c.getHighIndex());
    checkTest("safeArrayTests #38", 6, c.length());
    checkTest("safeArrayTests #39", -30, c[-20]);
    checkTest("safeArrayTests #40", -27, c[-17]);
    //attempt to write to c[-21] and c[-16] without crashing
    c[-21] = 1;
    c[-16] = 2;
    checkTest("safeArrayTests #41", 1, c[-21]);
    checkTest("safeArrayTests #42", 2, c[-16]);


    //Test an array of one element
    SafeArray d(3, 1);
    d[3] = 1111;

    checkTest("safeArrayTests #43", "1111", arrayToString(d));
    //Test methods
    checkTest("safeArrayTests #44", 3, d.getLowIndex());
    checkTest("safeArrayTests #45", 3, d.getHighIndex());
    checkTest("safeArrayTests #46", 1, d.length());
    //Test operator [] overload
    checkTest("safeArrayTests #47", 1111, d[3]);

    //Test resizing
    //Make sure the existing elements were untouched.
    d.resize(2, 2);
    checkTest("safeArrayTests #48", 2, d.getLowIndex());
    checkTest("safeArrayTests #49", 3, d.getHighIndex());
    checkTest("safeArrayTests #50", 2, d.length());
    checkTest("safeArrayTests #51", 1111, d[3]);
    //attempt to write to d[2] without crashing
    d[2] = 2222;
    checkTest("safeArrayTests #52", 2222, d[2]);



}

int main() {
    safeArrayTests();
#ifndef __GNUC__
    cout << "Press any key to continue" << endl;
    _getch();
#endif
}

解决方法: 解决方法: if (index > SafeArray::getHighIndex()) { throw 1; }

首先你似乎有一个逻辑错误:

您想支持自定义边界,所以 if (index >= capacity) 是错误的,因为您需要考虑 startingIndexcapacity 以获得正确的上限。

接下来,我没有测试比较 int 和 unsigned int 的效果,但你可能想在执行之前将 capacity 转换为更大的有符号类型比较。