【问题标题】:Problem creating and returning jagged array (error std::bad_array_new_length)创建和返回锯齿状数组时出现问题(错误 std::bad_array_new_length)
【发布时间】:2019-09-25 16:20:54
【问题描述】:

对于这个作业问题,我们需要使用教授提供的代码创建一个新的锯齿状数组,打印数组,并计算数组内容的最大值、最小值和总和。我们只允许编辑 createAndReturnJaggedArray()printAndThenFindMaxMinSum(int**,int*,int*,int*) 函数,因为其余代码是为我们提供的,因此我们可以检查是否得到正确的输出。

我能够让程序运行,但是在打印初始字符串后,它会终止程序,给我错误terminate called after throwing an instance of 'std::bad_array_new_length' what(): std::bad_array_new_length。我相信问题在于我创建了锯齿状数组以及我为数组的列部分分配了内存,但是我使用了我们提供的注释作为参考并且不知道问题出在哪里。下面提供了整个程序。感谢您的帮助!

编辑/注意:我们还没有学过向量,所以我们不能使用它们。

#include <iostream>
#include <climits>
using namespace std;

class JaggedArray {

public:

int numRows;
int *numColumnsInEachRow;
JaggedArray() {
    numRows = 11;
    numColumnsInEachRow = new int[numRows];
    for (int i = 0; i < numRows; i++) {
        if (i <= numRows / 2) {
            numColumnsInEachRow[i] = i + 1;
        } else {
            numColumnsInEachRow[i] = numRows - i;
        }
    }
    readComputeWrite();
}

int **createAndReturnJaggedArray() { // COMPLETE THIS FUNCTION
    int **A = new int*[numRows];
    for(int i=0;i<numRows;i++){ //allocate columns in each row
        A[i] = new int[numColumnsInEachRow[i]];
        for(int j=0;j<numColumnsInEachRow[i];j++){
            if(i <= numRows/2)
                A[i][j] = (i + j);
            else
                A[i][j] = -1 * (i+j);
        }
    }
    return A;
}

void printAndThenFindMinMaxSum(int **A, int *maxPtr, int *minPtr, int *sumPtr) { // COMPLETE THIS FUNCTION
    maxPtr = new int[INT_MIN];
    minPtr = new int[INT_MAX];
    sumPtr = 0;

    for(int i=0;i<numRows;i++){
       for(int j=0;j<numColumnsInEachRow[i];j++){
           //1. print array
            if (j == (numColumnsInEachRow[i]-1))
                cout << A[i][j] << endl;
            else
                cout << A[i][j] << " ";

           //2. compute max, min, and sum
           sumPtr += A[i][j];
           if (A[i][j] > *maxPtr)
                maxPtr = new int[A[i][j]];
           if (A[i][j] < *minPtr)
                minPtr = new int[A[i][j]];
        }
    }
}

void print(int max, int min, int sum) {
    cout << endl;
    cout << "Max is " << max << "\n";
    cout << "Min is " << min << "\n";
    cout << "Sum is " << sum << "\n";
}

void readComputeWrite() {
    int max, min, sum;
    int **A = createAndReturnJaggedArray();
    cout << "*** Jagged Array ***" << endl;
    printAndThenFindMinMaxSum(A, &max, &min, &sum);
    print(max, min, sum);
}
};

int main() {
    JaggedArray jaf;
    return 0;
}

【问题讨论】:

  • @Joseph Wood 是的,我们还没有学习矢量,因此不允许使用它们。 :\
  • @JosephWood 好电话,会的
  • maxPtr = new int[INT_MIN]; 在我看来有点问题。不知道你在这里做什么,但INT_MIN 是一个大的负数。数组和负数不能混用。 minPtr = new int[INT_MAX]; 是可能的,但可能需要 18 万亿字节的 RAM。祝你好运。 9万亿,对不起。蓝精灵。我出去了。 9 quintillion 字节。反正很多内存。
  • @user4581301 是的,这是有道理的。在作业指导中,我们的老师建议将maxPtr初始化为INT_MIN,将minPtr初始化为INT_MAX,并将sumPtr初始化为0。有没有更好的写法这样它不会溢出程序?
  • 阅读更多。在计算 min 和 max 时,通常每个只需要一个数字。例如,要获取数组中的最大值,您只需要存储到目前为止您见过的最大数字,以及最小的最小值。平均而言,您需要两个变量:到目前为止您看到的所有数字的总和(获取一个 BIG 数据类型来存储它)和您总结的数字的数量。

标签: c++ pointers jagged-arrays


【解决方案1】:

正如@user4581301 所暗示的,您的问题出在printAndThenFindMinMaxSum。只需将其更改为以下内容即可解决您的问题:

void printAndThenFindMinMaxSum(int **A, int &maxPtr, int &minPtr, int &sumPtr) { // COMPLETE THIS FUNCTION
    maxPtr = INT_MIN;
    minPtr = INT_MAX;
    sumPtr = 0;

    .
    .
    .
            sumPtr += A[i][j];
            if (A[i][j] > maxPtr)
                maxPtr = A[i][j];
            if (A[i][j] < minPtr)
                minPtr = A[i][j];
        }
    }
}

我们还需要把readComputeWrite改成:

void readComputeWrite() {
    int max, min, sum;
    int **A = createAndReturnJaggedArray();
    cout << "*** Jagged Array ***" << endl;
    printAndThenFindMinMaxSum(A, max, min, sum);
    print(max, min, sum);
}

我还建议将名称 minPtrmaxPtrsumPtr 更改为更合适的名称,因为此时它们不是指针,而是表示原始值。

您会注意到,我更改了指向引用的指针,因为这是对此类操作的更自然适应。本质上,通过引用传递允许用户以直接的方式对传递的值进行操作,而无需确保您在适当的时间取消引用事物的繁琐任务。它还允许人们以一种不易出错的方式进行操作。

同样,正如@user4581301 精明地指出的那样,这个赋值的目的可能是处理指针。因此,如果 OP 不能使用引用,则需要更改一些内容。观察:

void printAndThenFindMinMaxSum(int **A, int *maxPtr, int *minPtr, int *sumPtr) { // COMPLETE THIS FUNCTION
    *maxPtr = INT_MIN;  // Make sure to deference before assigning
    *minPtr = INT_MAX;  // Make sure to deference before assigning
    *sumPtr = 0;  // Make sure to deference before assigning

    for(int i=0;i<numRows;i++){
        for(int j=0;j<numColumnsInEachRow[i];j++){
            //1. print array
            if (j == (numColumnsInEachRow[i]-1))
                cout << A[i][j] << endl;
            else
                cout << A[i][j] << " ";

            //2. compute max, min, and sum
            *sumPtr += A[i][j];   // Make sure to deference before assigning
            if (A[i][j] > *maxPtr)  // Make sure to deference before comparing
                *maxPtr = A[i][j];  // Make sure to deference before assigning
            if (A[i][j] < *minPtr)  // Make sure to deference before comparing
                *minPtr = A[i][j];  // Make sure to deference before assigning
        }
    }
}

readComputeWrite 可以保持 OP 的原始尝试不变。

在 OP 的代码中,他们主要是在分配/比较之前忘记尊重。

【讨论】:

  • 哦嗬!你切换到我的参考!更好的主意,但我不确定教师是否允许参考。
  • @user4581301,快速提问。为什么导师不允许参考?我真的很好奇,相信你有充分的理由这么说。
  • 问题中的// COMPLETE THIS FUNCTION 注释和问题文本的开头段落。我怀疑导师交了一个骨架代码让学生填写,他们必须准确填写。我曾经经历过这样的任务,但是从教 Modula 的老师那里得到了与 Pascal 相同的课程计划。其他语言提供更好的解决方案这一事实似乎从未让他们意识到。
  • @JosephWood 谢谢!这更有意义,我可能想多了。你是救生员!
  • 没问题,但@user4581301 是真正的英雄,真正阐明了潜在问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-09
  • 2011-02-04
相关资源
最近更新 更多