数组索引越界赋值的问题

Issue with array index out of bounds assignment

本文关键字:问题 赋值 越界 索引 数组      更新时间:2023-10-16

我看过几篇类似的文章,但似乎没有一篇对我有帮助。如果有人能看看我的代码,告诉我我在这里做错了什么,我会很感激。我的老师帮不上什么忙。我在驱动程序中注释掉了第65 - 75行,因为我无法用这些来编译它,这也需要帮助

ArrayDriver.cpp

#include <iostream>
#include "myArray.h"
using namespace std;  
int main()
{ 
myArray<int> list1(5);
myArray<int> list2(5);
int i;
cout << "list1 : ";
for (i = 0 ; i < 5; i++)
    cout << list1[i] <<" ";
cout << endl;
cout << "Enter 5 integers: ";
for (i = 0 ; i < 5; i++)
    cin >> list1[i];
cout << endl;
cout << "After filling list1: ";
for (i = 0 ; i < 5; i++)
    cout << list1[i] <<" ";
cout<< endl;
list2 = list1;
cout << "list2 : ";
for (i = 0 ; i < 5; i++)
    cout << list2[i] <<" ";
cout<< endl;
cout << "Enter 3 elements: ";
for (i = 0; i < 3; i++)
    cin >> list1[i];
cout << endl;
cout << "First three elements of list1: ";
for (i = 0; i < 3; i++)
    cout << list1[i] << " ";
cout << endl;
myArray<int> list3(-2, 6);
cout << "list3: ";
for (i = -2 ; i < 6; i++)
    cout << list3[i] <<" ";
cout<< endl;
list3[-2] = 7;
list3[4] = 8;
list3[0] = 54;
list3[2] = list3[4] + list3[-2];
cout << "list3: ";
for (i = -2 ; i < 6; i++)
    cout << list3[i] <<" ";
cout<< endl;
/*
if (list1 == list2)
    cout << " list 1 is equal to list2 " << endl;
else
    cout << " list 1 is not equal to list2" << endl;
if (list1 != list2)
    cout << " list 1 is not equal to list2 " << endl;
else
    cout << " list 1 is equal to list2" << endl;
    */
//10% EXTRA CREDIT: UNCOMMENT CODE IF YOU'VE SUCCESSFULLY IMPLEMENTED THE FOLLOWING:
//cout << list1<< (list1 == list2 ? " is equal to" : " not equal to ") << list2 << endl;
//cout << list1<< (list1 != list2 ? " not equal to" : " is equal to ") << list2 << endl;
return 0;
}

myArray.h

#ifndef MYARRAY_H
#define MYARRAY_H
//#pragma once
#include <iostream>
//#include <assert.h>
//#include <iomanip>
//#include <string>
using namespace std;
template <class DataType>
class myArray
{
//overload for <<
//friend ostream& operator<<(ostream& out, myArray<DataType>& arr);
//overload for >>
friend istream& operator>>(istream& in, myArray<DataType>& arr);
public:
//myArray();
myArray(int size);
myArray(int start, int end);
//~myArray();
//overload []
DataType& operator[](int i);
//overload == operator
friend bool operator==(myArray<DataType> &arr1, myArray<DataType> &arr2);
//overload != operator
friend bool operator!=(myArray<DataType> &arr1, myArray<DataType> &arr2);
//overload = opertator
myArray<DataType> &operator=(const myArray<DataType> &rhs)
{
    if (myDataType != NULL)
        delete[]myDataType;
    myDataType = new DataType[rhs.arraySize];
    arraySize = rhs.arraySize;
    for (int i = 0; i < arraySize; i++)
        myDataType[i] = rhs.myDataType[i];
    return *this;
}
//function
void SetNULL();
protected:
int startIndex;
int endIndex;
int arraySize;
//template
DataType *myDataType;
};
#endif
template <class DataType>
DataType& myArray<DataType>::operator[](int i)
{
if (i > arraySize)
{
    cout << "Array out of bounds: " << endl;
}
else if (startIndex == 0)
{
    return myDataType[i];
}
else
{
    return myDataType[(startIndex + (i - 1))];
}
}
template <class DataType>
myArray<DataType>::myArray(int size) :
arraySize(size), startIndex(0), endIndex(size)
{
myDataType = new DataType[arraySize];
SetNULL();
}
template <class DataType>
myArray<DataType>::myArray(int start, int end) :
startIndex(start), endIndex(end)
{
if (start > end)
{
    cout << "Invalid start position: " << endl;
}
else
{
    arraySize = end - start;
}
myDataType = new DataType[arraySize];
SetNULL();
}
template <class DataType>
void myArray<DataType>::SetNULL()
{
for (int i = startIndex; i < endIndex; i++)
{
    myDataType[i] = (DataType)0;
}
}
//overload == operator
template <class DataType>
bool operator==(myArray<DataType> &arr1, myArray<DataType> &arr2)
{
bool testBool = true;
for (int i = 0; i < arraySize; i++)
{
    if (arr1[i] != arr2[i])
    {
        testBool = false;
    }
}
return testBool;
}
//overload != operator
template <class DataType>
bool operator!=(myArray<DataType> &arr1, myArray<DataType> &arr2)
{
bool testBool = true;
for (int i = 0; i < arraySize; i++)
{
    if (arr1[i] == arr2[i])
    {
        testBool = false;
    }
}
return testBool;
}
//overload >> operator
template <class DataType>
istream& operator>> (istream &in, myArray<DataType> &aList)
{
for (int i = 0; i < aList.arraySize; i++)
    in >> aList.list[i];
return in;
}

这就是为什么不忽略警告(或使用调试器)是有帮助的。我的编译器显示了这个问题(通过警告),这应该是你的问题的罪魁祸首。

在功能:

myArray<DataType> &operator=(const myArray<DataType> &rhs)
{
    if (myDataType = NULL)
        delete[]myDataType;
    myDataType = new DataType[rhs.arraySize];
    arraySize = rhs.arraySize;
    for (int i = 0; i < arraySize; i++)
        myDataType[i] = rhs.arraySize;
    return *this;
}

UPDATE:您还将数组大小分配为新创建副本的元素。复制实际元素

UPDATE #2:正如其他评论者指出的那样,您还忘记检查自赋值。检查当前数组的数组指针是否等于您正在分配的数组指针。

在第一个if语句中执行赋值而不是比较。考虑这样做:

myArray<DataType> &operator=(const myArray<DataType> &rhs)
{
    if (myDataType == rhs.myDataType)  //CHECK IF THE ARRAY IS THE SAME (self-assignment case).
        return *this;
    // Missing '!' character here!!!
    if (myDataType != NULL)
        delete[]myDataType;
    myDataType = new DataType[rhs.arraySize];
    arraySize = rhs.arraySize;
    for (int i = 0; i < arraySize; i++)
        myDataType[i] = rhs.myDataType[i]; // COPY ACTUAL ELEMENTS INSTEAD OF WRITTING ARRAY SIZE.
    return *this;
}

并且,为了避免将来出现这样的问题(如果您的编译器没有发现这样的问题,请考虑使用常量值进行比较,如下所示:

if (NULL != myDataType)
    delete[]myDataType;

然后你的编译器会,无论如何,拾取这个问题,因为它不能赋值给一个常量。

UPDATE #3:此外,正如我注意到的,您还允许数组具有用户定义的开始/结束索引。但是,您需要重新考虑当前计算索引的方法,以便在这种情况下(startIndex != 0)获得元素。您正在使用公式获得元素的位置:'startIndex + (i - 1)'。但是在您的测试用例中,在清单3中,索引的范围是[-2;6),然后开始for循环,初始索引等于-2 +(-2 - 1)= -2 - 3 = -5。我不知道为什么你的代码没有崩溃,但它应该。

另外,要实现比较操作符,首先要检查大小是否相同,因为如果其中一个数组较小,而您正在迭代较大数组的索引,当您访问不存在的索引时,它应该崩溃(老实说,如果数组的大小不同-它们不相等,不是吗?)。