Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Astrologer от Май 03, 2010, 16:27



Название: Application crash
Отправлено: Astrologer от Май 03, 2010, 16:27
Непонятно почему на строке
Код
C++ (Qt)
image_resampled.save(name_of_output_jpg);
приложение вдруг выходит с ошибкой "memory can't be read". Но что беспокоит меня - она иногда не появляется. Вот код функции (не судите строго за стиль =)) :
Код
C++ (Qt)
void MainWindow::algorithm(QString image_name)
{
 
  int counter = 0;
 
  QImage initial_image_tmp(image_name);
  int height_of_image = initial_image_tmp.height();
  initial_image_tmp.~QImage();
 
 double NDN = 889000;//should be defined
 double height = 830000;//should be defined
 //int height_of_image = 2384;
 int delta_r = 240; // should be defined
 //----------------------------------------//
 
 double NDK = NDN + delta_r * height_of_image;// estimate far slant distance
 double delta_R = NDK - NDN; // estimate pixel slant range step
 
 std::vector<double> slant_initial_vec;// define initial slant range vector
 
 double near_horiz_distance, far_horiz_distance, L_spheric;//define horizontal distances
 
 slant2range(NDN, height, near_horiz_distance);// slant to range distance convertion (near)
 slant2range(NDK, height, far_horiz_distance);// slant to range distance convertion(far)
 
 L_spheric = far_horiz_distance - near_horiz_distance;//define arc length which
                                                      //corresponds to slant range
 
 double size_tmp = L_spheric / delta_r;//define step at horiaontal range
 int size_of_output_array = (int)ceil(size_tmp);//compute size of output array (new image height)
 
 for (int i = 0; i < height_of_image; i++) slant_initial_vec.push_back(NDN + delta_r * i);//fill in initial slant vector
 
 std::vector<double> slant_vec;//horiaontal distances vector
 
 for (int i = 0; i < size_of_output_array; i++)//fill in resampled slant vector
 {
     double tmp_horiz = near_horiz_distance + i * delta_r;
     double tmp_slant;
     range2slant(tmp_horiz, height, tmp_slant);
 
     //-----------------------------------------//
     int counter = 100 * i /size_of_output_array;
     emit signal_update(counter);
     //-----------------------------------------//
 
     slant_vec.push_back(tmp_slant);
 }
 
 counter = 0;
 
 std::vector<int> indexes_lower, indexes_higher;//define indexes and delta vectors
 std::vector<double> delta_s;
 
 for (int i = 0; i < size_of_output_array; i++)
 {
     double out_slant_range, in_slant_range;
 
     out_slant_range = slant_vec[i];
     std::vector<double>::iterator range_iterator =
             std::lower_bound
             (slant_initial_vec.begin(),
              slant_initial_vec.end(),
              out_slant_range);
     in_slant_range = *range_iterator;
 
     int val = (int)(range_iterator - slant_initial_vec.begin());
     delta_s.push_back((out_slant_range - in_slant_range)/delta_r);
     indexes_lower.push_back(val);
     if (val >=height_of_image) indexes_higher.push_back(val);
     else indexes_higher.push_back(val + 1);
 
     int counter = 100 * i /size_of_output_array;
     emit signal_update(counter);
 }
 
 counter = 0;
 
 //----start processing-----------------------------//
 QImage initial_image(image_name);
 QString bmp_name = image_name + ".bmp";
 QImage initial_bmp = initial_image.copy(0,0, initial_image.width(), initial_image.height());
 initial_bmp.save(bmp_name);
 
 int initial_width = initial_image.width();
 int initial_height = initial_image.height();
 
 initial_image.~QImage();
 initial_bmp.~QImage();
 
 QImage image_resampled(initial_width, size_of_output_array, QImage::Format_ARGB32);
 image_resampled.fill(0);
 QString name_of_output_jpg = image_name + "_resampled.jpg";
 std::vector<double>
         input_green_vector,
         input_red_vector,
         input_blue_vector;
 
 //--------------------------//
 
 QImage tmp_bmp_image(bmp_name);
 
 //--------------------------//
 
 QRgb output_rgb_value;
 
 for (int j = 0;
      j < initial_width;
      j++)
 {
     get_current_column(//bmp_name,
                            tmp_bmp_image,
                            j,
                            input_red_vector,
                            input_green_vector,
                            input_blue_vector);
 
     for (int i = 0; i < size_of_output_array; i++)
          {
             double val_green = input_green_vector[indexes_lower[i]] *
                                (1- abs(delta_s[i])) +
                                input_green_vector[indexes_higher[i]] * abs(delta_s[i]);
 
             double val_red = input_red_vector[indexes_lower[i]] *
                                (1- abs(delta_s[i])) +
                                input_red_vector[indexes_higher[i]] * abs(delta_s[i]);
 
             double val_blue = input_blue_vector[indexes_lower[i]] *
                                (1- abs(delta_s[i])) +
                                input_blue_vector[indexes_higher[i]] * abs(delta_s[i]);
 
             //output_green_vector.push_back(val_green);
             //output_red_vector.push_back(val_red);
             //output_blue_vector.push_back(val_blue);
 
             output_rgb_value = qRgb(val_red, val_green, val_blue);
 
             image_resampled.setPixel(j, i, output_rgb_value);
         }
     int counter = 100 * j /initial_width;
     emit signal_update(counter);
}
 
 image_resampled.save(name_of_output_jpg);//save the image
 
 emit end_of_calculating();
 
}
 
 

Подскажите пожалуйста в чем тут может быть проблема.


Название: Re: Application crash
Отправлено: zenden от Май 03, 2010, 16:38
а зачем вы вызываете деструктор напрямую  ???


Название: Re: Application crash
Отправлено: Astrologer от Май 03, 2010, 17:06
Чтобы память сэкономить. Я комментил эти строки, не помогло.


Название: Re: Application crash
Отправлено: Sancho_s_rancho от Май 03, 2010, 20:10
Жуть какая. Зачем вы так издеваетесь над Qt и С++?
1) Деструктор НЕЛЬЗЯ вызывать явно, а в вашем коде это делаетеся во многих местах. Деструктор будет вызван второй раз когда выполнение дойдет до "}" и произойдут очень плохие вещи.
2) Если вы хотите очистить память сразу, то создавайте в куче объект.
Код:
QImage *myImage=new QImage();
delete myImage;

3)Приведение типа с округлением в большую сторону  выглядит подозрительно. Это действительно надо?
int size_of_output_array = (int)ceil(size_tmp);
4)Вызывается куча неизвестных функций. Может какая-то из них коробит данные.


Название: Re: Application crash
Отправлено: Alex Custov от Май 03, 2010, 20:15
Жуть какая. Зачем вы так издеваетесь над Qt и С++?
1) Деструктор НЕЛЬЗЯ вызывать явно, а в вашем коде это делаетеся во многих местах. Деструктор будет вызван второй раз когда выполнение дойдет до "}" и произойдут очень плохие вещи.

Можно, но в данном случае это может действительно приводить к краху.


Название: Re: Application crash
Отправлено: Astrologer от Май 03, 2010, 21:22
Жуть какая. Зачем вы так издеваетесь над Qt и С++?
1) Деструктор НЕЛЬЗЯ вызывать явно, а в вашем коде это делаетеся во многих местах. Деструктор будет вызван второй раз когда выполнение дойдет до "}" и произойдут очень плохие вещи.
3)Приведение типа с округлением в большую сторону  выглядит подозрительно. Это действительно надо?
int size_of_output_array = (int)ceil(size_tmp);

по 3) Надо, Федя, надо. (с).

С деструктором посмотрю. Не вижу никакой жути. А функции только обработку делают.


Название: Re: Application crash
Отправлено: lit-uriy от Май 03, 2010, 21:26
>>Чтобы память сэкономить.
Если жалко память, то ограничивайте область видимости:
Код
C++ (Qt)
{
QImage initial_image(image_name);
...
}
выйдя за область видимости (ограниченную фигурными скобками) объект созданный на стеке разрушется


Название: Re: Application crash
Отправлено: Astrologer от Май 03, 2010, 22:35
Код
C++ (Qt)
void MainWindow::algorithm(QString image_name)
{
 
  int counter = 0;
 
  QImage initial_image_tmp(image_name);
  int height_of_image = initial_image_tmp.height();
  initial_image_tmp.~QImage();
 
 double NDN = 889000;//should be defined
 double height = 830000;//should be defined
 int delta_r = 240; // should be defined
 //----------------------------------------//
 
 double NDK = NDN + delta_r * height_of_image;// estimate far slant distance
 double delta_R = NDK - NDN; // estimate pixel slant range step
 
 std::vector<double> slant_initial_vec;// define initial slant range vector
 
 double near_horiz_distance, far_horiz_distance, L_spheric;//define horizontal distances
 
 slant2range(NDN, height, near_horiz_distance);// slant to range distance convertion (near)
 slant2range(NDK, height, far_horiz_distance);// slant to range distance convertion(far)
 
 L_spheric = far_horiz_distance - near_horiz_distance;//define arc length which
                                                      //corresponds to slant range
 
 double size_tmp = L_spheric / delta_r;//define step at horiaontal range
 int size_of_output_array = (int)ceil(size_tmp);//compute size of output array (new image height)
 
 for (int i = 0; i < height_of_image; i++) slant_initial_vec.push_back(NDN + delta_r * i);//fill in initial slant vector
 
 std::vector<double> slant_vec;//horiaontal distances vector
 
 for (int i = 0; i < size_of_output_array; i++)//fill in resampled slant vector
 {
     double tmp_horiz = near_horiz_distance + i * delta_r;
     double tmp_slant;
     range2slant(tmp_horiz, height, tmp_slant);
 
     //-----------------------------------------//
     int counter = 100 * i /size_of_output_array;
     emit signal_update(counter);
     //-----------------------------------------//
 
     slant_vec.push_back(tmp_slant);
 }
 
 counter = 0;
 
 std::vector<int> indexes_lower, indexes_higher;//define indexes and delta vectors
 std::vector<double> delta_s;
 
 for (int i = 0; i < size_of_output_array; i++)
 {
     double out_slant_range, in_slant_range;
 
     out_slant_range = slant_vec[i];
     std::vector<double>::iterator range_iterator =
             std::lower_bound
             (slant_initial_vec.begin(),
              slant_initial_vec.end(),
              out_slant_range);
     in_slant_range = *range_iterator;
 
     int val = (int)(range_iterator - slant_initial_vec.begin());
     delta_s.push_back((out_slant_range - in_slant_range)/delta_r);
     indexes_lower.push_back(val);
     if (val >=height_of_image) indexes_higher.push_back(val);
     else indexes_higher.push_back(val + 1);
 
     int counter = 100 * i /size_of_output_array;
     emit signal_update(counter);
 }
 
 counter = 0;
 
 //----start processing-----------------------------//
 QImage initial_image(image_name);
 QString bmp_name = image_name + ".bmp";
 QImage initial_bmp = initial_image.copy(0,0, initial_image.width(), initial_image.height());
 
 int initial_width = initial_image.width();
 int initial_height = initial_image.height();
 
 QImage image_resampled(initial_width, size_of_output_array, QImage::Format_ARGB32);
 QString name_of_output_jpg = image_name + "_resampled.jpg";
 std::vector<double>
         input_green_vector,
         input_red_vector,
         input_blue_vector;
 
 QRgb output_rgb_value;
 
 for (int j = 0;
      j < initial_width;
      j++)
 {
     get_current_column(
                            initial_bmp,
                            j,
                            input_red_vector,
                            input_green_vector,
                            input_blue_vector);
 
     for (int i = 0; i < size_of_output_array; i++)
          {
             double val_green = input_green_vector[indexes_lower[i]] *
                                (1- abs(delta_s[i])) +
                                input_green_vector[indexes_higher[i]] * abs(delta_s[i]);
 
             double val_red = input_red_vector[indexes_lower[i]] *
                                (1- abs(delta_s[i])) +
                                input_red_vector[indexes_higher[i]] * abs(delta_s[i]);
 
             double val_blue = input_blue_vector[indexes_lower[i]] *
                                (1- abs(delta_s[i])) +
                                input_blue_vector[indexes_higher[i]] * abs(delta_s[i]);
 
             output_rgb_value = qRgb(val_red, val_green, val_blue);
 
             image_resampled.setPixel(j, i, output_rgb_value);
         }
     int counter = 100 * j /initial_width;
     emit signal_update(counter);
}
 
 image_resampled.save(name_of_output_jpg);//save the image
 
 emit end_of_calculating();
 
}
 

Код
C++ (Qt)
connect(this, SIGNAL(end_of_calculating()), this->prog_dlg, SLOT(close()));
 

Если несколько изображений подряд обрабатывать (по очереди), то иногда опять пишет что нельзя память прочитать. Кстати объект созданный без new, сам освобождает ресурсы при выходе из области видимости?


Название: Re: Application crash
Отправлено: lit-uriy от Май 04, 2010, 01:31
>>Кстати объект созданный без new, сам освобождает ресурсы при выходе из области видимости?
я тебе уже об этом написал

За одно компилятор увидит, если ты попытаешься к нему обратиться за областью видимости.