Ошибка сегментации при создании матриц - PullRequest
1 голос
/ 25 июля 2011

Я практиковался на c ++ в некоторых уроках и натолкнулся на урок, который создает матрицы, я хотел получить что-то большее от него и изменил его, я вообще не знаю матриц, потому что я еще не изучал их в школе, но этот код нижеиногда работает, иногда нет.Когда это не работает, я обычно получаю: Ошибка сегментации.почему это происходит?

до того, как это происходило каждый раз, но после того, как я присвоил 0 значение переменной line и member в начале, это больше не происходит, но все же, если я наберу excЛиния: 10Участник: 9это дает:1 1 1 1 1 1 1 1 1
1 2 3 4 5 1 7 8 9Ошибка сегментациии останавливается.Может кто-нибудь объяснить мне это?спасибо!

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

 int main()
 {
     int line=0,member=0;
     int i,j,matrice[line][member];

     cout << "\nLine: ";
         cin >> line;

     cout << "Member: ";
     cin >> member;

     cout << "\nCreated Matrice: \n" << endl;

         for (i=0;i<line;i++)
         {
             for (j=0;j<member;j++)
             {
                 matrice[i][j]=i*j+1;
                 cout << setw(5) << matrice[i][j];
             }
             cout << "\n\n";
         }
 return 0;
 }

Ответы [ 5 ]

4 голосов
/ 25 июля 2011
int line=0,member=0;
int i,j,matrice[line][member];

Эта строка не должна компилироваться.В стандартном C ++

  1. массивы 0 размера не допускаются
  2. размеры массивов должны быть константные выражения

Похоже, что ваш компилятор допускает это как расширения.В любом случае, когда вы позже введете line и member, ваш размер массива не изменится.Вы должны определить свой массив после ввода этих чисел.Но массив должен быть динамически размещен (еще лучше использовать vector s)

#include <vector>
//...
int line, member;
cin >> line  >> member;
vector<vector<int> > matrix(line, vector<int>(member));

или, если вы не хотите использовать вектор в образовательных целях, сделайте следующее:

int line, member;
int ** matrix;
cin >> line  >> member;
matrix = new int*[line];
for(int i = 0; i < line; ++i)
   matrix[i] = new int[member];

Не забудьте освободить матрицу.

for(int i = 0; i < line; ++i)
   delete [] matrix[i];
delete [] matrix;

Я предлагаю вам прочитать хорошую книгу по C ++

HTH

2 голосов
/ 25 июля 2011

Массив matrice инициализируется с размером [0][0], которые являются значениями line и member.Поскольку вы переопределяете значения с введенными значениями, границы, используемые в циклах for, недопустимы.

т.е. вы получаете доступ к элементам за пределами массива.

Возможно, вы захотите использоватьnew для динамического создания массивов или просто используйте std::vector, который изменяет размеры.

Кроме того, это не стандарт , но если ваш компилятор поддерживает его,Вы можете использовать массивы переменной длины.Они ведут себя как обычные массивы, но выделяются с использованием вычисляемого во время выполнения значения:

int line=0,member=0;
int i,j;

cout << "\nLine: ";
cin >> line;

cout << "Member: ";
cin >> member;

int matrice[line][member];

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

0 голосов
/ 25 июля 2011

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

Что касается производительности, я написал небольшой тест с использованием g ++ на Ubuntu 10.04. Запуск

г ++ - версия

Я получаю

g ++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

Моя тестовая программа создает матрицу 100x100 и устанавливает для каждого элемента определенное значение. Сначала у него есть несколько объявлений:

#include <vector>
#include <iostream>
#include "util.h" // Timer utilities.

#define LINE_COUNT (100) // The number of lines.
#define COL_COUNT (100) // The number of columns.

#define REPETITIONS (100000) // Number of repetitions for each test.

using namespace std;

Тогда у меня есть тест с использованием векторов:

void use_vectors()
{
  int line   = LINE_COUNT;
  int member = COL_COUNT;
  vector<vector<int> > matrix(line, vector<int>(member));

  // Set data.
  for (int i = 0; i < line; i++)
  {
    for (int j = 0; j < member; j++)
    {
      matrix[i][j] = -5;
    }
  }
}

Тогда у меня есть функция для выполнения того же теста (создание матрицы и установка значений) с использованием массивов:

void use_arrays()
{
  int line   = LINE_COUNT;
  int member = COL_COUNT;
  int **matrix; 

  matrix = new int * [line];
  for (int i = 0; i < line; i++)
  {
     matrix[i] = new int[member];
  }

  // Set data.
  for (int i = 0; i < line; i++)
  {
    for (int j = 0; j < member; j++)
    {
      matrix[i][j] = -5;
    }
  }

  for (int i = 0; i < line; ++i)
  {
     delete [] matrix[i];
  }

  delete [] matrix;
}

Основная программа повторяет оба теста и записывает время, необходимое для каждого из них. Вот основная программа:

main()
{
  long int es = 0;
  long int eu = 0;
  start_timer();
  for (int i = 0; i < REPETITIONS; i++)
  {
    use_vectors();
  }
  stop_timer();
  es = elapsed_sec();
  eu = elapsed_usec();
  cout << "Vectors needed: " << es << " sec, " << eu << " usec" << endl;

  start_timer();
  for (int i = 0; i < REPETITIONS; i++)
  {
    use_arrays();
  }
  stop_timer();
  es = elapsed_sec();
  eu = elapsed_usec();
  cout << "Arrays needed: " << es << " sec, " << eu << " usec" << endl;
}

Функции таймера основаны на библиотечной функции gettimeofday () (см., Например, http://linux.die.net/man/2/gettimeofday).

Результат следующий:

Vectors needed: 24 sec, 624416 usec
Arrays needed:  10 sec, 16970 usec

Так что у векторов есть некоторые накладные расходы на массивы. Или я могу сделать что-то, чтобы улучшить производительность векторов? Я несколько раз проверил свой тестовый код, и мне кажется, я понял его правильно.

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

0 голосов
/ 25 июля 2011

Вы хотите выделить память динамически.Затем используйте динамическое распределение, например:

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

 int main()
 {
     int line=0,member=0;
     int i,j;
     int **matrice; //Define matrice as a 2D array(a Matrix)

     cout << "\nLine: ";
         cin >> line;

     cout << "Member: ";
     cin >> member;

     //start of dynamic allocation
     matrice=new int*[line];
     for (i=0;i<line;i++)
           matrice[i]=new int[member];
     //End of dynamic allocation

     cout << "\nCreated Matrice: \n" << endl;

         for (i=0;i<line;i++)
         {
             for (j=0;j<member;j++)
             {
                 matrice[i][j]=i*j+1;
                 cout << setw(5) << matrice[i][j];
             }
             cout << "\n\n";
         }
 delete[] matrice;  //Releasing allocated memory
 return 0;
 }
0 голосов
/ 25 июля 2011

Вы используете динамический массив без выделения памяти, используя malloc или аналогичный.То есть в вашей строке int i,j,matrice[line][member]; не является массивом с постоянным размером, поэтому память должна выделяться динамически.Или используйте постоянный размер матикса, как предложено выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...