Russian Qt Forum

Программирование => Общий => Тема начата: daruma от Январь 10, 2018, 19:19



Название: Программе не хватает памяти?
Отправлено: daruma от Январь 10, 2018, 19:19
Добрый день!
Пишу программу с большим количеством вычислений. Много раз делается преобразование Фурье, много больших массивов (разные производные).
Отдельно Фурье работает, проверяла.
Код выглядит примерно так:

Код:
    double HMatrixFourRe[ImageHeight * ImageWidth];
    double HMatrixFourIm[ImageHeight * ImageWidth];
    double Denominator;

    Fourier(HMatrix, HMatrixFourRe, HMatrixFourIm, ImageWidth, ImageHeight, ImageWidth, ImageHeight);

    double WxFourRe[ImageHeight * ImageWidth];
    double WxFourIm[ImageHeight * ImageWidth];

    double WyFourRe[ImageHeight * ImageWidth];
    double WyFourIm[ImageHeight * ImageWidth];

    double Delta[ImageWidth * ImageHeight];

    if(ImageIRe == NULL)
    {
        ImageIRe = new double[ImageHeight * ImageWidth];
        ImageIIm = new double[ImageHeight * ImageWidth];
        Fourier(ImageI, ImageIRe, ImageIIm, ImageWidth, ImageHeight, ImageWidth, ImageHeight);
    }

    Fourier(Wx, WxFourRe, WxFourIm, ImageWidth, ImageHeight, ImageWidth, ImageHeight);
    Fourier(Wy, WyFourRe, WyFourIm, ImageWidth, ImageHeight, ImageWidth, ImageHeight);

    double ImageLFourReDerXL[ImageHeight * ImageWidth];
    double ImageLFourImDerXL[ImageHeight * ImageWidth];

    //dx
    Fourier(ImageLXDerivate, ImageLFourReDerXL, ImageLFourImDerXL, ImageWidth, ImageHeight, ImageWidth, ImageHeight);

    double ImageLFourReDerYL[ImageHeight * ImageWidth];
    double ImageLFourImDerYL[ImageHeight * ImageWidth];

    //dy
    Fourier(ImageLYDerivate, ImageLFourImDerYL, ImageLFourReDerYL, ImageWidth, ImageHeight, ImageWidth, ImageHeight);

Внутри Фурье постоянно возникает ошибка SIGSEGV. Если все массивы выделяю сразу, ошибка будет на первом же Фурье, если вот так последовательно - на последнем Фурье.
Это код внутри Фурье, ошибка возникает внутри цикла при row = 0:
Код:
double ColumnIn[ArrInHeight];
for(long row = 0; row < ArrInHeight; row++)
{
      ColumnIn[row] = ArrIn[row * ArrInWidth + col]; //здесь возникает ошибка
}

Проблема именно в ColumnIn (проверяла). Я плохо в таких вещах разбираюсь, как узнать, в чём именно проблема? (может стек переполнился... понятия не имею).

ОС: ubuntu14.04 LTS, 64-битная.
Оперативки: 2 гига.

Если кто-нибудь может подсказать, буду очень благодарна.


Название: Re: Программе не хватает памяти?
Отправлено: qate от Январь 10, 2018, 22:18
когда под отладчиком запускаешь - что показывает в момент сбоя ?

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

зы а почему 1404 ?


Название: Re: Программе не хватает памяти?
Отправлено: zhbr от Январь 11, 2018, 06:49
стэк кончился? может массивы динамически выделять?


Название: Re: Программе не хватает памяти?
Отправлено: Igors от Январь 11, 2018, 07:40
Выделять на стеке приличный массив не годится. Используйте контейнеры, хотя бы так
Код
C++ (Qt)
std::vector<double> ImageLFourReDerYL[ImageHeight * ImageWidth];
std::vector<double> ImageLFourImDerYL[ImageHeight * ImageWidth];
 
//dy
Fourier(ImageLYDerivate, &ImageLFourImDerYL[0], &ImageLFourReDerYL[0], ImageWidth, ImageHeight, ImageWidth, ImageHeight);
 
Еще лучше переписать ф-цию Fourier чтобы она тоже принимала контейнеры (это несложно), Сейчас это слишком длинная сопля, вызывать ее очень неудобно.

Вторая проблема
Код:
    if(ImageIRe == NULL)
    {
        ImageIRe = new double[ImageHeight * ImageWidth];
        ImageIIm = new double[ImageHeight * ImageWidth];
        Fourier(ImageI, ImageIRe, ImageIIm, ImageWidth, ImageHeight, ImageWidth, ImageHeight);
    }
Память выделенную под массивы надо затем освобождать с помощью delete []. Но здесь просто дописать delete [] в конце этого куска кода будет ошибкой т.к. ImageIRe мог быть и "не наш". Опять лучше задействовать контейнер, напр
Код
C++ (Qt)
size_t totalSize = ImageHeight * ImageWidth;
if (ImageIRe.size() != totalSize)
   {
       ImageIRe.resize(totalSize);
       ImageIIm.resize(totalSize);
       Fourier(ImageI, &ImageIRe[0], &ImageIIm[0], ImageWidth, ImageHeight, ImageWidth, ImageHeight);
   }


Название: Re: Программе не хватает памяти?
Отправлено: daruma от Январь 11, 2018, 15:55
когда под отладчиком запускаешь - что показывает в момент сбоя ?

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

зы а почему 1404 ?

Указывает на эту строчку и выводит Segmentation Fault. Больше никакой информации нет. Проблема именно в доступе к массиву,который выделен парой строк выше, отдельно код работает, поэтому кроме нехватки памяти у меня никаких идей нет...
Я причешу код и выложу.

PS
Потому что с виндой у меня не клеится, а последний раз обновляла систему очень давно (по принципу: пока всё работает и слава богу, не дышите на комп :) ).


Название: Re: Программе не хватает памяти?
Отправлено: daruma от Январь 11, 2018, 16:06
Выделять на стеке приличный массив не годится. Используйте контейнеры, хотя бы так
То есть они по-разному хранятся?

Цитировать
Память выделенную под массивы надо затем освобождать с помощью delete []. Но здесь просто дописать delete [] в конце этого куска кода будет ошибкой т.к. ImageIRe мог быть и "не наш".
Массив удаляется, но уже в самом конце, тк он почти всё время используется. Остальные массивы "временные", их значения вычисляются заново на каждой итерации, поэтому я не выделяла их динамически.


Название: Re: Программе не хватает памяти?
Отправлено: daruma от Январь 11, 2018, 16:13
стэк кончился? может массивы динамически выделять?

Это всё внутри функции, не уверена, что динамическое выделение чем-то поможет. Дальше идёт кусок кода, где это безобразие ещё по сто раз используется, то есть всё равно удалить ничего нельзя. Я поставила где можно области видимости, но это не спасло, ошибка стала вылезать на пару строк ниже (собственно, на этом моменте фантазия и истощилась).

В общем, выложу проект, а пока буду про хранение объектов в памяти читать.


Название: Re: Программе не хватает памяти?
Отправлено: Igors от Январь 11, 2018, 16:26
Массив удаляется, но уже в самом конце, тк он почти всё время используется. Остальные массивы "временные", их значения вычисляются заново на каждой итерации, поэтому я не выделяла их динамически.
Девонька, учите контейнеры, чем быстрее - тем лучше. Без них тут можно долго пыль глотать


Название: Re: Программе не хватает памяти?
Отправлено: Apktyc от Январь 11, 2018, 16:28
Если грубо, то:
Стек - маленький (пару мегабайт) и быстрый.
Куча - большая (уже гигабайты) и медленная.

У Вас идет выделение на стеке массивов для типа double (8 байт), на моей рабочей машине строчка
Код:
double Array[512 * 512]
уже вызывает SIGSEGV


Название: Re: Программе не хватает памяти?
Отправлено: qate от Январь 11, 2018, 21:39
Если грубо, то:
Стек - маленький (пару мегабайт) и быстрый.
Куча - большая (уже гигабайты) и медленная.

как это ?
я думал и стек и куча - это одна и та же память


Название: Re: Программе не хватает памяти?
Отправлено: Old от Январь 11, 2018, 21:43
как это ?
я думал и стек и куча - это одна и та же память
Имеется ввиду скорость аллокации.


Название: Re: Программе не хватает памяти?
Отправлено: daruma от Январь 14, 2018, 14:05
Девонька, учите контейнеры, чем быстрее - тем лучше. Без них тут можно долго пыль глотать

Контейнеры решили все проблемы. Спасибо!