数组索引超出边界分配的问题

时间:2015-10-18 16:39:50

标签: c++ arrays

我看过几篇关于类似内容的文章,但似乎没有一篇对我有所帮助。如果有人能看到我的代码并告诉我这里做错了什么,我将不胜感激。我的老师没多大帮助。我在驱动程序中注释掉了第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;
}

1 个答案:

答案 0 :(得分:0)

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

在功能中:

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

更新:您还将数组大小指定为新创建的副本的元素。复制实际元素。

更新#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)'。但是在你的测试用例中,在list3中,索引的范围是[-2; 6),并开始你的for循环,初始索引等于-2 +( - 2 - 1)= - 2 - 3 = -5。我不确定为什么你的代码没有在这里崩溃,但它应该。

另外,要实现比较运算符,首先检查大小是否相同,因为如果其中一个数组较小,并且您正在迭代较大数组的索引,那么当您访问时它会崩溃不存在的索引(说实话,如果数组的大小不同 - 它们不相等,是吗?)。