Ошибка времени выполнения c ++, когда 2d массиву присваивается другое значение массива - PullRequest
0 голосов
/ 22 марта 2020
#include<iostream>
#include<string>
#include <cstring>
using namespace std;

bool b[200][200];
int a[46];
int test_cases;
int n;
int m;
int first;
int second;

int main()
{
  cin>>test_cases;
  while(test_cases--){

    cin>>n;
    cin>>m;

    for (int i=0;i<2*m;i++){
      cin>>a[i];
    }
    for (int j=0;j<m;j++){
      first=a[2*j];
      second=a[2*j+1];
      b[first][second]=true;

    }

  }

  return 0;
}

Привет. Кажется, во время выполнения последнего кода произошла ошибка времени выполнения 'b [first] [second] = true;'

Я перепробовал несколько изменений и обнаружил, если я включу 'b [first] [second] = true;' в 'b [second] [first] = true;' Ошибка не возникает, что просто изменить порядок индексов.

Нет возможности "ошибки вне диапазона", поскольку объем памяти b равен [200] [200], а диапазон результатов a [*] составляет от 0 до 10.

Я не могу понять, откуда проблема, и мне нужна помощь. Спасибо.

1 Ответ

1 голос
/ 22 марта 2020

Нет возможности "ошибки вне диапазона", поскольку объем памяти b равен [200] [200], а диапазон результатов a [*] составляет от 0 до 10.

Мир полон глючного кода, потому что люди делают подобные предположения. первая вещь, которую вы должны сделать, это доказать это правильно. Это так же просто, как поместить что-то вроде:

if (first < 0 || first > 199 || second < 0 || second > 199) {
    cerr << "Violation, first = " << first << ", second = " << second << "\n";
    exit(1);
}

непосредственно перед вашей строкой, которая устанавливает для элемента b[][] значение true.


Кроме того, это также будет Целесообразно также проверить доступ к другим массивам. Поскольку у нас нет ваших тестовых данных, мы не знаем, какое значение будет вводиться для n или m, но, поскольку эти значения могут привести к неопределенному поведению (при доступе за пределами массива), их также следует тщательно изучить .

Если вы хотите быть уверенными в том, что это не вызывает проблем, вы можете динамически выделить правильный размер при необходимости. Например, как только вы получили m от пользователя:

int *a = new int[m*2];
// Use it as you wish, elements <0..m*2-1> inclusive.
delete [] a;
...