Как исправить «0xC0000005: место чтения нарушения доступа» в C ++ - PullRequest
0 голосов
/ 16 апреля 2020

Недавно я научился писать программы по оптимизации на c ++. Я получал одно и то же сообщение, когда строил свою модель оптимизации:

введите описание изображения здесь

Может кто-нибудь мне помочь или сказать, что там происходит? Большое спасибо.

#include <ilcplex/ilocplex.h> ILOSTLBEGIN

typedef IloArray<IloNumVarArray> IloNumVarArray2;

int main(int argc, char ∗∗argv) {
  IloEnv env;

  try {
    const char;

    IloInt i, j;
    IloModel mod(env);

    IloNumVarArray2 x(env);
    for (i = 0; i < 3; i++) {
      x.add(IloNumVarArray(env, 2, 0.0, IloInfinity));
    }

    mod.add(IloMaximize(
        env, 6.5 * x[0][0] + 11 * x[0][1] + 9.75 * x[1][0] + 12.25 * x[1][1] +
                 9.5 * x[1][2] + 4.75 * x[2][0] + 7.75 * x[2][1] +
                 8.5 * x[2][2] + 7.5 * x[3][0] + 8.5 * x[3][1]));
    mod.add(x[0][0] + x[1][0] + x[2][0] + x[3][0] >= 500);
    mod.add(x[0][1] + x[1][1] + x[2][1] + x[3][1] >= 600);
    mod.add(x[0][2] + x[1][2] + x[2][2] + x[3][2] >= 500);

    mod.add(x[0][0] + x[0][1] <= 600);
    mod.add(x[1][0] + x[1][1] + x[1][2] <= 500);
    mod.add(x[2][0] + x[2][1] + x[2][2] <= 300);
    mod.add(x[3][0] + x[3][1] <= 400);

    IloCplex cplex(mod);

    if (!cplex.solve()) {
      env.error() << "Failed to optimize LP." << endl;
      throw(-1);
    }

    IloNumArray vals(env);
    env.out() << "Solution status = " << cplex.getStatus() << endl;
    env.out() << "Solution value = " << cplex.getObjValue() << endl;
    env.out() << "Values = " << vals << endl;

  } catch (IloException &e) {
    cerr << "Error 2" << e << endl;
  } catch (...) {
    cerr << "Error 1" << endl;
  }
  env.end();

  return 0;
}

1 Ответ

1 голос
/ 17 апреля 2020

Как и люди в предложенных комментариях, используйте отладчик, чтобы отследить проблему. Еще лучше: скомпилируйте вашу программу в режиме отладки. Код IloCplex содержит большое количество утверждений в заголовочных файлах, которые улавливают распространенные ошибки. Запуск вашего кода в режиме отладки приводит к ошибке подтверждения:

X& IloArray::operator[] (IloInt i) : Out of bounds operation: index superior to size of array
segfault2.bin++: concert/include/ilconcert/iloenv.h:2246: X& IloArray<X>::operator[](IloInt) [with X = IloNumVarArray; IloInt = long int]: Assertion `(i < _impl->getSize()) || (std:: cerr << "X& IloArray::operator[] (IloInt i) : Out of bounds operation: index superior to size of array" << std:: endl, ilo_stop_assert())' failed.
Aborted

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

mod.add(IloMaximize(
    env, 6.5 * x[0][0] + 11 * x[0][1] + 9.75 * x[1][0] + 12.25 * x[1][1] +
             9.5 * x[1][2] + 4.75 * x[2][0] + 7.75 * x[2][1] +
             8.5 * x[2][2] + 7.5 * x[3][0] + 8.5 * x[3][1]));

Вы получаете доступ к x[3][*], хотя массив x содержит только 3 элемента. Таким образом, только индексы 0, 1, 2 действительны для этого массива. Кроме того, вы обращаетесь к x[*][2] в некоторых местах, хотя второе измерение вашего массива - только 2.

...