c ++ stl вектор вызывает переполнение памяти? - PullRequest
1 голос
/ 20 декабря 2010

Я широко использую векторы stl для управления выделением памяти большими массивами данных. В частности, я создаю перспективные проекции анатомических структур с большим количеством углов (180 с шагом 2 градуса), обрабатываю и анализирую результаты. Результаты используются для определения полей излучения для лучевой терапии.

Кажется, что если массивы превышают определенный размер (> 3 анатомических структуры), то память переполняется. В частности, ошибка заключается в следующем

прекращение вызова после выброса экземпляра 'std :: out_of_range' что (): вектор :: _ M_range_check

Это результат использования at, который выполняет проверку границ, а не более быстрого оператора []. Если у меня <= 3 структуры, ошибка не возникает. </p>

Я отследил ошибку до следующего блока кода

bool dicomCP::assignBeamlet(int beamletNumber, Beamlet &b1)
{
 //std::cout << "\nInside dicomCP::assignBeamlet (int, Beamlet &)\n";

  if (!this->isSet)
  {
   this->beamlets.at(beamletNumber).setLeftRight(b1.left,b1.right);

   this->isSet=true;

   return true;


  }

  else if (!this->beamlets.at(beamletNumber-1).isOpen())
  {

   return false;

  }

  // left (outside) min(left) and right (outside) max(right) leaves
  else if ((this->beamlets.at(beamletNumber-1).right-b1.left >EPSILON2)&&(b1.right-this->beamlets.at(beamletNumber-1).left>EPSILON2))
  {

   if (this->beamlets.at(beamletNumber).open) return false;

   else if (!this->beamlets.at(beamletNumber).open)
   {
   this->beamlets.at(beamletNumber).setLeftRight(b1.left,b1.right);
   this->beamlets.at(beamletNumber).isAssigned=true;



   this->isSet=true;
   return true;
   }
  }

  else return false;

}

Обратите внимание, что если "this-> isSet = true;" строки закомментированы, ошибка не проявляется независимо от количества структур: да, она работает с 6! Логическое значение isSet используется для определения того, какие объекты были установлены, и, следовательно, какие объекты необходимо записать в файл данных для дальнейшей обработки.

Система и программное обеспечение:

gcc (SUSE Linux) 4.4.1 [версия gcc-4_4-branch 150839] SuSE 11.2 64bit Intel Celsius с 4 процессорами Xeon 2,66 ГГц и 4 ГБ оперативной памяти Eclipse CDT (IDE) 64 бит, сборка 20100218-1602

Ответы [ 4 ]

2 голосов
/ 20 декабря 2010

Видимо, вы получаете доступ к элементам вне контейнера.Из этого кода невозможно сказать, правильны ли индексы, пройдитесь по этому коду в отладчике, и вы увидите.Подозрительно выглядящий фрагмент: this->beamlets.at(beamletNumber-1).isOpen() Что, если beamletNumber равен 0?Вы получаете неверный индекс.

2 голосов
/ 20 декабря 2010

Я предполагаю, что вы передаете beamletNumber == 0, который затем становится (без знака) -1, или, другими словами, очень большим числом.

at (largenumber) затем бросает

1 голос
/ 20 декабря 2010

at () вызывает исключение.Если индекс выходит за пределы диапазона, он генерирует исключение out_of_range.

Проверьте, соответствует ли (beamletNumber / beamletNumber-1) индексу в векторе, в котором существует элемент.at () проверяет его и выдает исключение.

Исключение класса out_of_range используется для сообщения о том, что значение аргумента не находится в ожидаемом диапазоне, например, когда неправильный индекс используется вмассив или строка, похожая на массив.

0 голосов
/ 20 декабря 2010

вы используете как this-> beamlets.at (beamletNumber-1), так и this-> beamlets.at (beamletNumber).

this-> beamlets.at (beamletNumber-1) предполагает, что вы обрабатываете вектор с помощью индексов на основе 1, тогда как this-> beamlets.at (beamletNumber) предлагает индексы на основе 0.

с индексами на основе 1 this-> beamlets.at (beamletNumber), безусловно, приведет к ошибке вне диапазона.

с индексами на основе 0 this-> beamlets.at (beamletNumber-1), безусловно, приведет к ошибке вне диапазона.

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