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)
是错误的,因为您需要考虑 startingIndex
和 capacity
以获得正确的上限。
接下来,我没有测试比较 int 和 unsigned int 的效果,但你可能想在执行之前将 capacity
转换为更大的有符号类型比较。
好的,所以我为我的 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)
是错误的,因为您需要考虑 startingIndex
和 capacity
以获得正确的上限。
接下来,我没有测试比较 int 和 unsigned int 的效果,但你可能想在执行之前将 capacity
转换为更大的有符号类型比较。